Несоответствие типов с генериками - PullRequest
3 голосов
/ 03 ноября 2008

Вот интерфейс:

public interface Foo<T> extends Comparable<Foo<T>>  {
   ...
}

И есть несколько классов, реализующих этот интерфейс:

public class Bar extends Something implements Foo<Something> {
    public Vector<Foo<Bar>> giveBar() {
        ...
    }
}

public class Boo extends SomethingElse implements Foo<SomethingElse> {
    public Vector<Foo<Boo>> giveBoo() {
        ...
    }
}

Теперь я хочу сохранить группу векторов Foos (это могут быть Foos или Boos) внутри вектора.

Bar bar = new Bar();
Boo boo = new Boo();
Vector<Foo<?>> vector;
if (...) 
   vector = bar.giveBar();
else
   vector = boo.giveBoo();

Я получаю:

Type mismatch: cannot convert from Vector<Foo<SomethingElse>> to Vector<Foo<?>>

То же самое касается:

Vector<Foo> vector;
if (...) 
   vector = giveBar();
else
   vector = giveBoo();

Является ли суперкласс, который как Bar, так и Boo расширяет единственное решение этой проблемы?

Ответы [ 2 ]

6 голосов
/ 03 ноября 2008

К чему сводится весь этот код:

Vector<A> vector = new Vector<B>();

В этом случае B расширяет A, но это недопустимо, потому что типы не совпадают. Чтобы понять, почему это не работает, представьте следующий код:

Vector<Vector<?>> vector = new Vector<Vector<String>>();
vector.add(new Vector<Integer>());

Тип переменной - это вектор векторов неизвестного типа ; и ему присваивается вектор векторов строк . Во второй строке к этому добавляется вектор целых чисел . Тип компонента переменной Vector<?>, который принимает Vector<Integer>; но фактический тип компонента вектора Vector<String>, который не делает. Если компилятор не возражает против присвоения в первой строке, он позволит вам написать неверную вторую строку, не будучи замеченным.

Обобщения C # имеют аналогичное ограничение, но отличие состоит в том, что универсальный класс в C # сохраняет тип компонента, в то время как Java забывает типы компонентов при компиляции кода.

пс - с какой стати вы используете Vector вместо LinkedList или ArrayList? Это из-за проблем с многопоточностью?

2 голосов
/ 03 ноября 2008

Вы можете использовать

Vector<? extends Foo<?>> vector;
...