猿问

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

为什么以下不起作用?


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;

}

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


Java 环境:java 11.0.4 2019-07-16 LTS


繁星淼淼
浏览 109回答 2
2回答

慕虎7371278

我的理解是,通用方法/类/接口将被编译为单个类文件,其中类型参数被替换为最合适的下限您的理解是正确的,但编译器旨在更智能地处理泛型。如果编译器的设计完全按照您所描述的方式设计,那么泛型的意义何在?我可以写一个方法Integer来代替。不需要泛型,因为编译器只会替换我拥有的任何类型参数Integer。您已指定它T必须是Integer或 的子类Integer。想想当T是 的子类时的情况Integer,下面的赋值仍然有效吗?不会的!t&nbsp;=&nbsp;Integer.valueOf(2);&nbsp;//&nbsp;you&nbsp;are&nbsp;assigning&nbsp;an&nbsp;instance&nbsp;of&nbsp;a&nbsp;superclass&nbsp;to&nbsp;a&nbsp;subclass&nbsp;variable您可能会争辩说Integer不能有任何子类final,但编译器并不是为了检查final这种情况下类的性质而设计的。在这里用作Integer界限可能意味着它reassign根本不应该是通用的。编译器做的另一件事是在必要时插入强制转换,但这与这个问题并不真正相关。

胡说叔叔

它不起作用的原因是编译器无法证明它T实际上是T. 整数在这里是一个坏例子,因为它是最终的,没有人可以扩展它,但编译器不够智能,无法知道这一点并对其进行推理。假设您有以下内容&nbsp;class Foo{&nbsp;}&nbsp;class Bar extends Foo {&nbsp;}你像这样调用重新分配reassign(new Bar());允许重新分配的地方<T extends Foo> T reassign(T t){&nbsp; &nbsp; t = new Foo();&nbsp; &nbsp; return t;}那么这相当于说Bar b = new Foo()这当然是无效的
随时随地看视频慕课网APP

相关分类

Java
我要回答