[英]Cannot assign valid constant(value) to a Generic Type variable
为什么以下不起作用?
void execute() {
Integer a = Integer.valueOf(1);
a = reassign(a);
D.log("a: " + a);
}
<T extends Integer> T reassign(T t) {
t = Integer.valueOf(2); // error: incompatible types: Integer cannot be converted to T
// t = (T) Integer.valueOf(2); // This works but with warning: [unchecked] unchecked cast
return t;
}
<T extends Integer> T reassign2(T t, T anotherT) {
t = anotherT; // This works without any warning.
return t;
}
我的理解是泛型方法/类/接口将被编译为单个 class 文件,其中类型参数被替换为最合适的下限(在上述情况下为整数)。
Java 环境:java 11.0.4 2019-07-16 LTS
我的理解是泛型方法/类/接口将被编译为单个 class 文件,其中类型参数替换为最合适的下限
您的理解是正确的,但编译器旨在更智能地处理 generics。 如果编译器完全按照您描述的方式设计,那么 generics 有什么意义? 我可以只写一个采用Integer
的方法。 不需要 generics,因为无论如何编译器只会用Integer
替换我拥有的任何类型参数。
您已指定T
必须是Integer
或Integer
的子类。 想想当T
是Integer
的子类时的情况,下面的赋值仍然有效吗? 它不会!
t = Integer.valueOf(2); // you are assigning an instance of a superclass to a subclass variable
您可能会争辩说Integer
不能有任何子类,因为它是final
,但编译器并非旨在检查这种情况下类的final
性。 在这里使用Integer
作为界限可能意味着reassign
根本不应该是通用的。
编译器做的另一件事是在必要时插入强制转换,但这与这个问题并不真正相关。
它不起作用的原因是编译器无法证明T
实际上是而不是T
的子类型。 Integer 在这里是一个不好的例子,因为它是最终的,没有人可以扩展它,但是编译器不够聪明,无法知道这一点并对其进行推理。
想象一下你有以下
class Foo{
}
class Bar extends Foo {
}
你像这样调用重新分配
reassign(new Bar());
允许重新分配的地方
<T extends Foo> T reassign(T t){
t = new Foo();
return t;
}
那么这相当于说
Bar b = new Foo()
这当然是无效的
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.