无法将有效常量(值)分配给泛型类型变量

时间:2019-10-05 16:38:13

标签: java generics

为什么以下各项不起作用?

read(2)

我的理解是,通用方法/类/接口将被编译为单个类文件,其中类型参数将替换为最合适的下限(在上述情况下为Integer)。

Java env:java 11.0.4 2019-07-16 LTS

2 个答案:

答案 0 :(得分:1)

  

我的理解是,通用方法/类/接口将被编译为单个类文件,其中类型参数将替换为最合适的下限

您的理解是正确的,但是编译器旨在更智能地处理泛型。如果完全按照您描述的方式设计编译器,那么泛型有什么意义?我可以只写一个使用Integer的方法。不需要泛型,因为编译器 just 仍然会用Integer替换我拥有的任何类型参数。

您已指定T必须是IntegerInteger的子类。考虑一下TInteger的子类时的情况,以下分配是否仍然有效?不会!

t = Integer.valueOf(2); // you are assigning an instance of a superclass to a subclass variable

您可能会争辩说Integer不能像final那样具有任何子类,但是在这种情况下,编译器并非旨在检查类的final的性质。在这里使用Integer作为界限可能意味着reassign根本不是通用的。


编译器要做的另一件事是在必要时插入强制类型转换,但这与该问题并没有实际关系。

答案 1 :(得分:1)

之所以不起作用,是因为编译器无法证明T实际上不是T的子类型。整数在这里是一个不好的例子,因为它是最终的,没有人可以扩展它,但是编译器不够聪明,无法知道它并对此进行推理。

假设您有以下内容

 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()

那当然是无效的