2013-10-09 54 views
0

在這個類兩種add方法具有相同的擦除簽名:爲什麼不能在Java中取消刪除類型?

class extend 
{ 
    Integer add (Integer a, Integer b) 
    { 
    return a + b; 
    } 

    <Type extends Integer> Type add (Type a, Type b) 
    { 
    return 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) 

在第一種情況下,編譯器知道擦除類型,並在第二種情況下,他再次忘記它?爲什麼?

+0

無論如何,鑑於'Integer'是一個最終的類,有一個具有'extends Integer'邊界的泛型類型有什麼好處?如果語言甚至不嘗試僅僅因爲沒有用就支持泛型類型的兩個值之間的加法,我就不會感到驚訝。 –

回答

1

您的方法<Type extends Integer> Type add (Type a, Type b)可以用Integer參數調用。 <Type extends Integer>邊界允許Integer或Integer的子類型。 如果有人寫這樣的代碼:

Integer i = 1; 
Integer k = 2; 
add(i, k); 

這是不可能的,以確定調用哪個方法,因爲他們都接受整數參數,也不比其他更具體。

如果你有add(Integer, Integer)add(Number, Number)整數加將被調用,因爲它更具體。但在您的情況下,如果使用Integer,論點IntegerInteger or subclass同樣具體。

也不要指望+運營商工作的任何子類。拆箱是特定類型的,因爲它尋找特定的類型,需要能夠轉換爲int並實例化裝箱值。

+0

這個問題不是爲什麼這兩種方法有相同的擦除。我知道拆箱是特定類型的。問題是爲什麼一個普通類型和一個擦除類型在拆箱時不以相同的方式處理,而是在涉及方法簽名時以相同的方式處理。這在編譯器中是不一致的,我想知道它爲什麼存在? – ceving

+0

由於類型刪除遵循一般類型規則集,但拆箱涉及特定的6種左右類型,並且您的泛型允許在該點使用更多類型而不僅僅是那些類型。拆箱可與Integer一起使用,您的泛型聲明允許對於Integer和其他一些不適用於拆箱的子類型,這就是編譯器拒絕這種使用的原因。 –

相關問題