дженерики с супер - PullRequest
       19

дженерики с супер

1 голос
/ 23 марта 2012

В

public class Organic<E> {
    void react(E e) {
    }

    static void main(String[] args) {
        Organic<? super Elem2> compound = new Organic<Elem>();
        compound.react(new Elem());
    }
}

class Elem {}

class Elem2 extends Elem {}

Почему возникает ошибка компиляции

Метод реагировать (захват # 1-из? Super Elem2) в типе Organic не применим для аргументов (Elem)

Ответы [ 4 ]

2 голосов
/ 23 марта 2012

Используя super, вы определяете нижнюю границу вашего параметра типа. Вы говорите, что фактический тип вашего органического объекта имеет тип Elem2 или один из его супертипов. Таким образом, компилятор заменяет сигнатуру вашего метода реагирования для Elem2, например

void react(Elem2 value) {}

Таким образом, вы не можете передать новый Elem () вашему объекту, потому что это потребует снижения рейтинга.

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

public static void main(String[] args) {
    Organic<Object> all = new Organic<Object>();
    Organic<? super Elem2> other = all;

    Elem a = new Elem2();
    other.react((Elem2)a);
}

Кроме того, вы можете delcare как

    Organic<? super Elem> other = ...;

Что должно сработать.

0 голосов
/ 23 марта 2012

Ограниченный шаблон в List может захватывать Elem2 и любой из его супертипов. Поскольку Elem2 расширяет Elem, это означает, что единственными типами, которые в настоящее время могут быть преобразованы при захвате с помощью List, являются:

List<Elem2>
List<Elem>
List<Object>
0 голосов
/ 23 марта 2012

Это должно работать

    Organic<Elem> compound = new Organic<Elem>();

Это не сработает, потому что они являются символами подстановки (работа с назначением, реакция на вызов не будет)

  Organic<?> compound = new Organic<Elem>();
  Organic<? extends Elem> compound = new Organic<Elem>();
  Organic<? super Elem2> compound = new Organic<Elem>();

Вы могли бы также сделать

<F> void react(F e) {
}

Тогда вы могли бы работать с подстановочными знаками

Понятия не имею, почему вы хотите работать с подстановочными знаками

0 голосов
/ 23 марта 2012

Компилятор не должен смотреть на фактическое значение составного, а только на его объявление. И ? может быть Elem2 сам по себе. И это должно позволить вам не звонить Organic<Elem2>.react(Elem).

...