2013-10-09 5 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 и Integer or subclass одинаково специфичны, если используется Integer.

Также не ожидайте, что оператор + будет работать с любыми подклассами. Unboxing специфичен по типу, так как он ищет определенные типы, требует возможности конвертировать в int и создавать экземпляры в штучной упаковке.

+0

Вопрос не в том, почему оба метода имеют одно и то же стирание. И я знаю, что unboxing имеет тип. Вопрос в том, почему простой тип и стираемый тип не обрабатываются одинаково, когда дело доходит до unboxing, но обрабатываются таким же образом, когда речь заходит о сигнатурах методов. Это несоответствие в компиляторе, и я хотел бы знать, почему он существует? – ceving

+0

Поскольку стираемые стили следуют общему набору правил типа, но unboxing относится к определенным типам 6 или около того, а ваш общий тип позволяет использовать больше типов, которые будут использоваться в этом месте, чем только эти. 6. Unboxing работает с Integer, ваше общее объявление позволяет для Integer и множества других подтипов, которые не будут работать с распаковкой, поэтому компилятор отказывается от этого использования. –