2009-09-07 6 views
4

Я не понимаю, почему следующий код генерирует предупреждение.Java: Generic casting down генерирует предупреждение, почему?

interface Generic<T> { 
} 

interface A { 
} 

class B { 
    Generic<A> c; 

    <T extends A> B(Generic<T> a) { 
     c = (Generic<A>) a; //warning here 
    } 

} 

//Unchecked cast from Generic<T> to Generic<A> 

В классе B я заинтересован только в использовании экземпляров Generic, которые типа А. Это предупреждение свидетельствует о том, что мне нужно хранить Generic аргумент как Т вместо А.

Но это означает, что мне также придется объявить B generic, что, похоже, усложняет ситуацию, чем нужно.

+0

Что происходит, когда вы не бросаете? – aperkins

+0

ошибка несоответствия типа – Mike

ответ

6

Это не вниз для литья под давлением, так как Java дженерик инвариантны: Generic<T> не подтип Generic<A> даже если T является подтипом A. Если вам нужны только общие методы, которые возвращают A, вы можете использовать подстановочные Generic<? extends A> в B конструктор и в поле, в котором хранится ссылка.

5

Потому что Generic<T> не является под -типом Generic<A>, даже если T является подтипом A.

Чтобы проиллюстрировать это, рассмотрим String экземпляр Object:

List<String> listOfStrings = new ArrayList<String>(); 
List<Object> listOfObjects = (List<Object>)listOfStrings; // invalid 
listOfObjects.add(new Date()); 
// now listOfStrings contain a date! 

Компилятор не допускает, что бросок, потому что это может привести к коррупции исходного списка. JVM не применяет общие требования к границам во время выполнения.

Решение здесь состоит в том, чтобы указать поле c типа 'Generic`.

+1

классический пример опасностей дженериков в java –