2016-07-08 4 views
5

В моем проекте возникла странная проблема. Теперь я упростил задачу и написал небольшой пример здесь, чтобы проиллюстрировать мою растерянность:Что случилось с ключевым словом «супер» в Java generic type

public class Question { 
    class Q1 {} 

    class Q2 extends Q1 {} 

    interface In<T> { 
     void f(T t); 
    } 

    List<Q2> list; 

    void f(In<? super List<? super Q2>> in) { 
     in.f(list); 
    } 

    static void g() { 
     Question question = new Question(); 
     In<Collection<Q1>> in1 = new In<Collection<Q1>>() { 
      @Override 
      public void f(Collection<Q1> o) {} 
     }; 
     In<List<Q2>> in2 = new In<List<Q2>>() { 
      @Override 
      public void f(List<Q2> o) {} 
     }; 
     question.f(in1); //Error! 
     question.f(in2); //Error! 
    } 
} 

Моя цель состоит в том, чтобы сделать метод f(In<? super List<? super Q2>>) более гибким. Я могу передать in1 или in2. Но ни один из них не может быть передан! Что не так?

Возможно, this answer будет иметь смысл. Но мой вопрос другой! Мой общий тип - In<? super List<? super Q2>>, общий тип в общем типе.

+0

@AndyTurner "все соответствует? Super Q2", так почему 'question.f (in1)' является ошибкой? вы можете очистить больше? – Jerry06

+0

@ Jerry06 Думаю, я неверно истолковал вопрос. Возобновлено. –

ответ

0
In<Collection<? extends Q1>> in1 = new In<Collection<? extends Q1>>() { 
      @Override 
      public void f(Collection<? extends Q1> o) {} 
     }; 
     In<List<? extends Q2>> in2 = new In<List<? extends Q2>>() { 
      @Override 
      public void f(List<? extends Q2> o) {} 
     }; 
+0

'продюсер' отличается. Легче. Пожалуйста, измените его на 'super' и посмотрите, что произойдет. –

+0

да. Такая же ошибка с супер – Gangadhar

2

Общий тип формы A<? extends B> означает, что ? может быть заменен B или любой супер-типа B. Таким образом, List<? super Q2> означает что-то вроде: либо List<Object>, List<Q1>, либо List<Q2>.

Хотя Q1 супер-тип Q2, List<Q1> не супер-тип List<Q2>. Это означает, что единственным общим супертипом List<Object>, List<Q1> и List<Q2> является Object. Таким образом, единственное, что вы можете передать вашему методу f, - это In<Object>.

Как вам нужно решить это зависит от того, какую гибкость вам действительно нужно: какие объекты вы хотите передать f и что делать с этими объектами?

+0

Как насчет '> '? И что мне делать, если я хочу передать любой подкласс 'Collection' в' f'? –

Смежные вопросы