Java方法中的动态返回类型

Java方法中的动态返回类型,java,dynamic,return-type,Java,Dynamic,Return Type,我在这里多次看到类似的问题,但有一个很大的区别 在其他问题中,返回类型由参数确定。我想要/需要做的是通过字节[]的解析值来确定返回类型。根据我收集的信息,以下几点可能有效: public Comparable getParam(String param, byte[] data) { if(param.equals("some boolean variable") return data[0] != 0; else(param.equals("some float

我在这里多次看到类似的问题,但有一个很大的区别

在其他问题中,返回类型由参数确定。我想要/需要做的是通过
字节[]
的解析值来确定返回类型。根据我收集的信息,以下几点可能有效:

public Comparable getParam(String param, byte[] data) {
    if(param.equals("some boolean variable")
        return data[0] != 0;
    else(param.equals("some float variable") {
        //create a new float, f, from some 4 bytes in data
        return f;
    }
    return null;
}

我只是想在我把事情搞砸之前,确保这一切都有可能成功。提前感谢。

如果您实际上只返回一个
布尔值
浮点值
,那么您最好只返回
对象


如果要返回变量对象,则必须选择具有最不常见超类的返回类型。原语没有超类,但它们将被装箱到对象表示中(如
布尔型
浮点型
),它们有一个共同的超类
对象

,您不能这样做。Java返回类型必须是固定的基本类型 或对象类。我很确定你能做的就是返回一个包装器类型 它具有获取各种可能类型的值的方法和内部枚举 这说明哪一个是有效的

---编辑---在丹尼斯纠正之后

public <Any> Any getParam(boolean b){
return((Any)((Boolean)(!b)));
}
public <Any> Any getParam(float a) {
 return((Any)((Float)(a+1)));
}
public <Any> Any getParam(Object b) {
 return((Any)b);
}
public void test(){
  boolean foo = getParam(true);
  float bar = getParam(1.0f);
  float mumble = getParam(this); // will get a class cast exception
}
public任意getParam(布尔b){
返回((任意)((布尔值)(!b));
}
公共任意getParam(浮点a){
回报率((任何)((浮动)(a+1));
}
public Any getParam(对象b){
返回((任何)b);
}
公开无效测试(){
布尔值foo=getParam(true);
浮动条=getParam(1.0f);
float mumble=getParam(this);//将获得类强制转换异常
}
您仍然会因装箱项目和类型检查而受到一些处罚 返回的值,当然如果您的调用与 getParam的实现实际上是做什么的,您将得到一个类
例外。

我不知道这些人在说什么。您失去了类型安全性,这是一个值得关注的问题,但您可以通过泛型轻松实现这一点……类似于:

public <T> T getSomething(...) { }
publictgetsomething(…){

接口包装器{T getObject();}
公共包装器getSomething(…){}
后者促进了发生冲突的可能性。将字节传递给策略,让它执行并检索输出。您可以使用字节策略、布尔策略等

abstract class Strategy<T> {
    final byte[] bytes;

    Strategy(byte[] bytes) { this.bytes = bytes; }

    protected abstract T execute();
}
抽象类策略{
最终字节[]字节;
策略(字节[]字节){this.bytes=bytes;}
受保护的抽象T execute();
}
然后

类布尔策略扩展策略{
公共布尔策略(字节[]字节){super(字节);}
@凌驾
公共布尔执行(){
返回字节[0]!=0;
}
}

不过,您的示例代码是一个糟糕的用例,我不推荐使用它。你的方法没有多大意义。

是可以做到的。以下代码将起作用:

public byte BOOLEAN = 1;
public byte FLOAT = 2;
public static <Any> Any getParam(byte[] data) {
    if (data[0] == BOOLEAN) {
        return (Any)((Boolean)(boolean)(data[1] != 0));
    } else if (data[0] == FLOAT) {
        return (Any)((Float)(float)data[1]);
    } else {
        return null;
    }
}
如果不使用此技巧,最好是手动投射对象:

float f = (float)getParam(data);

Java动态返回类型可以减少样板代码。

我的2美分,以Google HTTP客户端为例:

static public <Any> Any getJson(final String url, final Class<Any> parseAs) throws IOException {
        HttpRequestFactory requestFactory
                = HTTP_TRANSPORT.createRequestFactory(
                (HttpRequest request) -> {
                    request.setParser(new JsonObjectParser(JSON_FACTORY));
                });

        HttpRequest request = requestFactory.buildRequest(HttpMethods.GET, new GenericUrl(url), null);

        return request.execute().parseAs(parseAs);
    }
static public任何getJson(最终字符串url,最终类parseAs)都会引发IOException{
HttpRequestFactory请求工厂
=HTTP_TRANSPORT.createRequestFactory(
(HttpRequest请求)->{
setParser(新的JsonObjectParser(JSON_工厂));
});
HttpRequest请求=requestFactory.buildRequest(HttpMethods.GET,新的GenericUrl(url),null);
返回request.execute().parseAs(parseAs);
}
可以这样使用:

HashMap<String, Object> out = HttpUtils.getJson( "https://api.qwant.com", HashMap.class);
HashMap out=HttpUtils.getJson(“https://api.qwant.com,HashMap.class);

您不能从带有签名的方法返回
float
boolean
(顺便说一句,它应该是
compariable
)。您只能返回
Float
Boolean
,等等。对于我的情况,可能有一个更好的问题是“是否有一种方法可以转换返回类型,以便在不必转换为变量的情况下调用该方法?”而不是在纯Java中。(IIRC,可以用Java字节码完成,但我可能会被MSIL弄糊涂。)我几乎投了赞成票,但你说
Object
是基本体的常见超类。在Java中,事实并非如此。原语没有通用的超类,尽管它们可以被装箱到等效的引用类型中。原语不是对象,但会自动装箱到这些对象中,这是正确的。我正在更新我的答案以反映这一点。你能举个例子吗?还是指给我看?我理解你的意思,但是看代码要容易得多。公共类genericvalue{String returnStringvalue(){}int returnIntvalue(){}等等,每个方法都会尽一切努力生成所需类型的值。@ddyer你的答案不正确。在Java中可以有动态返回类型。看看我下面的答案,看一个适合这个问题的例子。@danieth哇!我完全错过了这一点通用类型的魔术。对于基本类型,它似乎需要对项目进行装箱和拆箱,并且总是需要对接收端进行类型检查,但它肯定可以用于生成更干净、更自然的代码。我认为您在这方面走的是对的,但我不太明白您的建议。在这个问题中,Jon有一个
字节[]
,希望传入一个字符串并返回一个值,他可以将该值分配给原语而无需强制转换。我认为这实际上是不可能的。没错,如果不传递字符串,而是传递一些更复杂的对象,则可以利用泛型来获取正确类型的值。另一方面,如果不进行至少一次未检查的强制转换,则无法实现
T getSomething()
方法,因此,如果使用不正确,则可能会在运行时失败(例如,
布尔foo=getSomething(“someFloatParam”);
)。
float f = (float)getParam(data);
static public <Any> Any getJson(final String url, final Class<Any> parseAs) throws IOException {
        HttpRequestFactory requestFactory
                = HTTP_TRANSPORT.createRequestFactory(
                (HttpRequest request) -> {
                    request.setParser(new JsonObjectParser(JSON_FACTORY));
                });

        HttpRequest request = requestFactory.buildRequest(HttpMethods.GET, new GenericUrl(url), null);

        return request.execute().parseAs(parseAs);
    }
HashMap<String, Object> out = HttpUtils.getJson( "https://api.qwant.com", HashMap.class);