Проблема приведения типов Java

Возможные дубликаты:
Как преобразовать Vector‹ObjectA› в Vector‹ObjectB› в Java?
Является ли List<Dog> подклассом List<Animal>? Почему дженерики Java не являются неявно полиморфными?

У меня логическая проблема с приведением типов java. У меня есть класс A, который расширяет класс B, и поэтому у меня может быть такой оператор, как A a = new B();, но почему я получаю ошибку компилятора для Vector<A> va = new Vector<B>(); или Vector<A> va = (Vector<A>)new Vector<B>();


person Rey    schedule 26.05.2011    source источник
comment
Вам нужен подстановочный знак, Vector<? extends A> va. Многие вопросы SO будут указывать на информацию, например. stackoverflow.com/questions/252055/java-generics-wildcards   -  person Michael Brewer-Davis    schedule 27.05.2011
comment
Это распространенное заблуждение относительно дженериков. Вектор‹A› НЕ является подтипом Вектора‹B›. Прочтите [Книгу об общих принципах] (amazon.com/ Java-Generics-Collections-Maurice-Naftalin/dp/)   -  person wolfcastle    schedule 27.05.2011
comment
Спасибо за ссылки, теперь понятно   -  person Rey    schedule 27.05.2011


Ответы (3)


дженерики Java не поддерживают ковариантность, поэтому Vector<B> НЕ расширяет Vector<A>

person amit    schedule 26.05.2011

Подумайте об этом так;

Если C также расширяет B, то вы можете поместить C в Vector<B>.

Теперь, если бы вы могли привести его к Vector<A> и сделали get, вы бы получили экземпляр C!

Это не имело бы особого смысла, поэтому компилятор этого не допускает. Как говорит @amit, Co-variance — это имя для этого.

См. это сообщение

person Jim    schedule 26.05.2011

Тип переменной должен соответствовать типу, который вы передаете фактическому типу объекта.

Когда дело доходит до полиморфизма в отношении универсального типа, java не позволяет вам сделать следующее:

class A { } 
class B extends A { } 
List<A> myList = new ArrayList<B>();

Это связано с тем, что при компиляции компилятор избавляется от универсальной типизации (с помощью чего-то, что называется стиранием типа) и делает то, что использовалось в коде до Java 5. Это сбивает с толку, потому что это не то же самое поведение с массивами. С массивами вы можете сделать:

A[] myArr = new B[10];

Но это не относится к дженерикам. Опять же, когда дело доходит до дженериков, тип переменной должен соответствовать типу, который вы передаете фактическому типу объекта.

Надеюсь, это поможет!

person secreteyes    schedule 26.05.2011