为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

繁星淼淼 2023-09-27 16:05:38
为什么以下不起作用?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
查看完整描述

2 回答

?
慕虎7371278

TA贡献1802条经验 获得超4个赞

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

您的理解是正确的,但编译器旨在更智能地处理泛型。如果编译器的设计完全按照您所描述的方式设计,那么泛型的意义何在?我可以写一个方法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这种情况下类的性质而设计的。在这里用作Integer界限可能意味着它reassign根本不应该是通用的。


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


查看完整回答
反对 回复 2023-09-27
?
胡说叔叔

TA贡献1804条经验 获得超8个赞

它不起作用的原因是编译器无法证明它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()

这当然是无效的


查看完整回答
反对 回复 2023-09-27
  • 2 回答
  • 0 关注
  • 108 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信