我有以下两个类(class):
public class GenericNumberOperation {
public GenericNumberOperation() {}
public <T extends Number> T getSomeValue (boolean tf) {
T number;
if(tf) {
number = new Double(1.0);
}
else {
number = new Integer(11);
}
return (T) number;
}
}
并且:
public class GenericNumberTest {
public GenericNumberTest() {}
public static void main(String[] args) {
GenericNumberOperation gno = new GenericNumberOperation();
Double d = gno.getSomeValue(true);
Integer i = gno.getSomeValue(false);
}
}
当我运行测试时,一切都很顺利。如果我将类型参数化更改为:
public <T> T getSomeValue(boolean tf)
编译器提示,报告:
错误:不兼容的类型 Integer 无法转换为 T 数字=新整数(11); 其中 T 是类型变量 T 扩展了 getSomeValue(boolean) 方法中声明的对象
它对 Double 也有类似的提示。为什么?
编辑: 我犯了一个错误。这实际上是有效的代码。
public class GenericNumberOperation {
public GenericNumberOperation() {}
public <T extends Number> T getSomeValue (boolean tf) {
Number number;
if(tf) {
number = new Double(1.0);
}
else {
number = new Integer(11);
}
return (T) number;
}
}
现在我明白了@Sotirios 的意思。
最佳答案
忘记你想用它做什么。我们只会从语言的角度来看待这个问题。
声明
public <T extends Number> T getSomeValue (boolean tf) {
定义了一个以Number
为边界的新类型T
。这意味着调用者在调用该方法时只能将 Number
或 Number
的任何子类型绑定(bind)到 T
。在该方法中,您不知道该类型可能是什么。
因此你不能这样做
T number = new Double(1.0);
因为你不知道T
是Double
。如果我调用该方法为
Float f = genOp.getSomeValue(true);
T
应该是Float
。编译器无法保证类型安全,因此会拒绝它(方法内的赋值,如果允许的话,则会在运行时抛出ClassCastException
)。如果您使用强制转换,您就告诉编译器您确定自己在做什么。它会警告你,但它会信任你。
同样,声明
public <T> T getSomeValue(boolean tf)
定义了一个无界的新类型T
。这意味着您可以将任何类型绑定(bind)到 T
,这使得问题变得更加严重。我现在可以做
String f = genOp.getSomeValue(true);
关于Java:转换为类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46475914/