Java方法中的动态返回类型

Jon*_*and 12 java dynamic return-type

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

在其他问题中,返回类型由参数确定.我想要/需要做的是通过a的解析值确定返回类型byte[].根据我的收集,以下内容可行:

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;
}
Run Code Online (Sandbox Code Playgroud)

我只想确保在我搞砸之前有机会工作.提前致谢.

Dan*_*eth 21

CAN来完成.以下代码将起作用:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

通过对返回类型使用泛型,任何Java方法都可以动态返回任何对象或基元类型.您可以根据需要命名通用名称,在这种情况下我将其称为"任意".使用此代码可以避免在调用方法时转换返回类型.你会使用这样的方法:

byte[] data = new byte[] { 1, 5 };
boolean b = getParam(data);
data = new byte[] { 2, 5 };
float f = getParam(data);
Run Code Online (Sandbox Code Playgroud)

没有这个技巧你可以做的最好的事情就是手动转换一个Object:

float f = (float)getParam(data);
Run Code Online (Sandbox Code Playgroud)

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


his*_*ess 18

我不知道这些人在谈论什么.你失去了类型安全,这是一个问题,但你可以通过泛型轻松实现这一点...类似于:

public <T> T getSomething(...) { }
Run Code Online (Sandbox Code Playgroud)

要么

interface Wrapper<T> { T getObject(); }

public <T> Wrapper<T> getSomething(...) { }
Run Code Online (Sandbox Code Playgroud)

后者促进了战略模式的可能性.将字节传递给策略,让它执行并检索输出.您将拥有字节策略,布尔策略等.

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

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

    protected abstract T execute();
}
Run Code Online (Sandbox Code Playgroud)

然后

class BooleanStrategy extends Strategy<Boolean> {
    public BooleanStrategy(byte[] bytes) { super(bytes); }

    @Override
    public Boolean execute() {
        return bytes[0] != 0;
    }

}
Run Code Online (Sandbox Code Playgroud)

您的示例代码虽然是一个糟糕的用例,但我不推荐它.你的方法没有多大意义.

  • 另一方面,你没有办法实现你的`T getSomething()`方法,至少没有未经检查的强制转换,所以如果使用不正确你可能会在运行时失败(例如`Boolean foo = getSomething("someFloatParam");` ).那时,你可能最好只使用一个显式的强制转换,因为那时很明显你可以得到一个`ClassCastException`. (2认同)

ddy*_*yer 13

你不能这样做.Java返回类型必须是固定的基本类型或对象类.我非常确定你能做的最好的事情是返回一个包装器类型,它有方法来获取各种可能类型的值,以及一个内部枚举,它说明哪一个是有效的.

---编辑---经过Danieth的修正!

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
}
Run Code Online (Sandbox Code Playgroud)

您仍然会对装箱物品进行一些处罚并对返回值进行类型检查,当然如果您的调用与getParam实际执行的操作不一致,您将获得一个类强制转换异常.