Могу ли я добавить в общую коллекцию значений типа A типа B, которая расширяет A, без какого-либо специального синтаксиса? - PullRequest
2 голосов
/ 31 августа 2011
public class Stack<E> {
    public Stack () {....}
    public void push (E e) {....}
    public E pop () {....}
    public boolean isEmpty(){....}
}

public void pushAll (Collection<E> src) {
    for (E e: src){
        push(e)
    }
}

Я не понимаю, в чем проблема, если я напишу

Stack<number> numberStack = new Stack<Number>();
Collection<Integer> integers=...
numberStack.pushAll(integers);

Целое число расширяет число, поэтому я могу добавить коллекцию целых чисел к numberStack. Но мне сказали, что это ошибка компиляции - почему?

Ответы [ 3 ]

12 голосов
/ 31 августа 2011

Ваш код указывает, что он только принимает Collection с таким же параметром типа , как у Stack.

Вы должны написать метод pushAll следующим образом:

public void pushAll (Collection<? extends E> src)

Это означает, что вы ожидаете Collection из некоторого типа, который расширяет E (т.е. вам не важно, какой это конкретный тип, но должен быть E или некоторый его подтип).

Посмотрите на определение Collection.addAll(): оно определено таким же образом.

1 голос
/ 31 августа 2011

Эта проблема связана с тем, что коллекции в Java не являются ковариантными . Есть много вопросов о SO, таких как this .

1 голос
/ 31 августа 2011

проблема в том, что у вас есть два типа, но только одно общее представление (E), поэтому E - это число, а также целое число.Это смущает его.Вы должны иметь тот же тип для коллекции.Перепишите его на

pushAll(Collection<K> src) 

и приведите K к E.

...