What is wrong with the keyword "super" in the Java generic type

There was a strange problem in my project. Now I have simplified the problem and written a small example here to illustrate my confusion:

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! } } 

My goal is to make the f(In<? super List<? super Q2>>) method more flexible. I can pass in1 or in2 method. But not one of them can be transmitted! What's wrong?

Perhaps this answer will make sense. But my question is different! My common type is In<? super List<? super Q2>> In<? super List<? super Q2>> In<? super List<? super Q2>> , a generic type in a generic type.

+5
source share
2 answers

General type type A<? extends B> A<? extends B> means what ? can be replaced by B or any supertype B So List<? super Q2> List<? super Q2> means something like: either List<Object> , List<Q1> , or List<Q2> .

Although Q1 is a supertype of Q2 , List<Q1> not a supertype of List<Q2> . This means that the only common supertype List<Object> , List<Q1> and List<Q2> is Object . So the only thing you can pass to your f method is In<Object> .

How you need to solve this depends on what kind of flexibility you really need: what objects do you want to pass to f and what to do with these objects?

+2
source
 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
source

All Articles