首页 > 解决方案 > 无法将有效常量(值)分配给通用类型变量

问题描述

为什么以下不起作用?

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

标签: javagenerics

解决方案


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

您的理解是正确的,但编译器旨在更智能地处理泛型。如果编译器完全按照您描述的方式设计,那么泛型有什么意义?我可以写一个方法来Integer代替。不需要泛型,因为编译器只会替换我拥有的任何类型参数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这种情况下类的完整性。在这里使用Integeras a bound 可能意味着它reassign根本不应该是通用的。


编译器做的另一件事是在必要时插入强制转换,但这与这个问题并不真正相关。


推荐阅读