我有以下两节课:
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)
编译器抱怨,报告:
错误:类型不兼容的整数不能转换为T number = new Integer(11); 其中T是类型变量T扩展了在方法getSomeValue(boolean)中声明的Object
它同样对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) {
定义一个T以限制的新类型Number。这意味着,一个呼叫者只能绑定Number或任何亚型Number到T调用方法时。在该方法中,您不知道该类型可能是什么。
T
Number
因此,你不能做
T number = new Double(1.0);
因为你不知道那T是Double。如果我将方法调用为
Double
Float f = genOp.getSomeValue(true);
T应该是Float。编译器不能保证类型安全,因此拒绝它(方法内的分配,如果允许的话,ClassCastException将在运行时抛出)。如果使用强制转换,则是告诉编译器您确定自己在做什么。它会警告您,但会信任您。
Float
ClassCastException
同样,声明
定义一个T无界的新类型。这意味着您可以将任何类型绑定到T,这使问题更加严重。我现在可以做
String f = genOp.getSomeValue(true);