我有简单的泛型类,如下所示:
public class Test<T extends Number> {
public void doSomething() {
Test t = new Test();
t.getNumber();
}
public T getNumber() {
T d = new Double("1.5"); // I get an compiler error here!
return d;
}
}
getNumber方法返回T(扩展Number),并在其实现中实例化Double。编译器在行上抛出错误:
T d = new Double("1.5"); // I get an compiler error here!
错误是:
Incompatible types:
[ERROR] found : java.lang.Double
[ERROR] required: T
由于T扩展了Number,我原本预计这会起作用。我错过了什么吗?
答案 0 :(得分:3)
T extends Number,但这并不意味着它扩展了Double。 Double只是Number的已知子类之一。
答案 1 :(得分:1)
在左侧使用通用参数并在右侧使用特定实现是不对的。
答案 2 :(得分:1)
想象一下,您实例化Test<Integer>
。然后getNumber
方法中的行变为:
整数d = new Double(“1.5”);
显然,它应该抛出编译器错误。
我认为您不应该使用泛型类型参数 - 将您的类替换为:
public class Test {
public Number getNumber() {
Number d = Double.valueOf("1.5"); // No compiler error
return d;
}
}
另一个解决方案是表达你可以使用Double的任何超类作为类型参数的条件,即:
public class Test<T super Double> {
public T getNumber() {
T d = Double.valueOf("1.5"); // No compiler error
return d;
}
}
一些一般提示:
new
来实例化盒装基元类型,而是使用装箱类中的静态工厂方法。答案 3 :(得分:0)
T d = (T)new Double("1.5");
你必须输入强制转换为T.虽然它解决了你的问题但我对你正在做的事情感到怀疑。
答案 4 :(得分:0)
泛型类型定义class Test<T extends Number>
表示选择创建Test
类对象的人可以选择使用哪个类型参数。用户选择的不是您作为类实现者。
这意味着您无法确定它的类型,因此您的getNumber()
方法只能安全地
T
对象null
T
的其他方法返回的对象。
Class<T>
(或Class<? extends T>
)Collection<T>
(或Collection<? extends T>
)