为什么不能在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和一系列其他子类型,这些子类型不能使用取消装箱,这就是为什么编译器拒绝使用这种方法。