为什么不能在Java中取消对已擦除类型的装箱?
此类中的两个为什么不能在Java中取消对已擦除类型的装箱?,java,type-erasure,unboxing,Java,Type Erasure,Unboxing,此类中的两个add方法具有相同的已擦除签名: class extend { Integer add (Integer a, Integer b) { return a + b; } <Type extends Integer> Type add (Type a, Type b) { return a + b; } } 类扩展 { 整数相加(整数a、整数b) { 返回a+b; } 类型添加(类型a、类型b) { 返回a+b; } } 这使得
add
方法具有相同的已擦除签名:
class extend
{
Integer add (Integer a, Integer b)
{
return a + b;
}
<Type extends Integer> Type add (Type a, Type b)
{
return a + b;
}
}
类扩展
{
整数相加(整数a、整数b)
{
返回a+b;
}
类型添加(类型a、类型b)
{
返回a+b;
}
}
这使得他们不可能都在同一个班。编译器报告以下错误:
extend.java:8: error: name clash: add(Type,Type) and add(Integer,Integer) have the same erasure
Type add (Type a, Type b)
^
where Type is a type-variable:
Type extends Integer declared in method add(Type,Type)
extend.java:10: error: incompatible types
return a + b;
^
required: Type
found: int
where Type is a type-variable:
Type extends Integer declared in method add(Type,Type)
extend.java:8:error:name clash:add(Type,Type)和add(Integer,Integer)具有相同的擦除
类型添加(类型a、类型b)
^
其中Type是类型变量:
类型扩展方法add中声明的整数(类型,类型)
但是,如果它们相等,为什么在第二种情况下不进行拆箱呢。编译器报告以下错误:
extend.java:8: error: name clash: add(Type,Type) and add(Integer,Integer) have the same erasure
Type add (Type a, Type b)
^
where Type is a type-variable:
Type extends Integer declared in method add(Type,Type)
extend.java:10: error: incompatible types
return a + b;
^
required: Type
found: int
where Type is a type-variable:
Type extends Integer declared in method add(Type,Type)
extend.java:10:错误:不兼容的类型
返回a+b;
^
必填项:类型
找到:int
其中Type是类型变量:
类型扩展方法add中声明的整数(类型,类型)
在第一种情况下,编译器知道被擦除的类型,而在第二种情况下,他又忘记了它?为什么?您的方法类型add(类型a,类型b)
可以使用整型
参数调用<代码>边界允许整数或整数的子类型。
如果有人编写此代码:
Integer i = 1;
Integer k = 2;
add(i, k);
不可能确定调用哪个方法,因为它们都接受整数参数,而且两者都不比另一个更具体
如果有add(Integer,Integer)
和add(Number,Number)
则会调用Integer add,因为它更具体。但是在您的例子中,如果使用了整型
,则参数整型
和整型或子类
同样特定
也不要期望+操作符处理任何子类。取消装箱是特定于类型的,因为它查找特定类型,需要能够转换为int并实例化装箱值。鉴于
Integer
是最后一个类,拥有一个绑定为extends Integer
的泛型类型有什么好处?如果该语言不支持泛型类型的两个值之间的加法,仅仅因为它没有用处,我也不会感到惊讶。问题不是为什么这两个方法具有相同的擦除。我知道拆箱是特定于类型的。问题是,为什么普通类型和擦除类型在解装箱时处理方式不同,而在方法签名时处理方式相同。这是编译器中的一个不一致性,我想知道它为什么存在?因为类型擦除遵循一组通用的类型规则,但取消绑定涉及到特定的6个左右的类型,并且您的泛型类型允许在该位置使用比这6个更多的类型。取消装箱可以使用Integer,您的泛型声明允许使用Integer和一系列其他子类型,这些子类型不能使用取消装箱,这就是为什么编译器拒绝使用这种方法。