2016-07-08 60 views
5

我的项目中遇到了一个奇怪的问题。现在,我已经简化了这个问题,在这里写了一个小例子来说明我的困惑:Java通用类型中的“super”关键字有什么问题

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>>)更加灵活。我可以通过in1in2该方法。但都不能通过!哪里不对?

也许this answer会有一定的意义。但我的问题是不同的!我的泛型类型是In<? super List<? super Q2>>,泛型类型中的泛型类型。

+0

@AndyTurner“一切都匹配?超级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

'extend'是不同的。这很容易。请把它改成'super',看看会发生什么。 –

+0

是的。与超级相同的错误 – Gangadhar

2

一个通用型的形式A<? extends B>的指?可由B或任何超类型的B代替。因此,List<? super Q2>表示类似于:List<Object>,List<Q1>List<Q2>

虽然Q1Q2的超级类型,但是List<Q1>不是超级类型的List<Q2>。这意味着List<Object>,List<Q1>List<Q2>唯一常见的超级类型是Object。所以你唯一可以传给你的f方法是In<Object>

你需要怎样解决这个问题取决于你实际需要什么样的灵活性:你想要传递什么样的对象到f以及这些对象想做什么?

+0

'<?扩展List <?扩展Q1 >>'?如果我想将'Collection'的任何子类传递给'f',该怎么办? –