简体   繁体   中英

What's wrong with the “super” keyword in Java generic type

I encountered 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 aim is to make the method f(In<? super List<? super Q2>>) more flexible. I can pass in1 or in2 to the method. But neither can be passed! What is wrong?

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

A generic type of the form A<? extends B> A<? extends B> means that the ? can be replaced by B or any super-type of B . Thus, List<? super Q2> List<? super Q2> means something like: either List<Object> , List<Q1> or List<Q2> .

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

How you need to solve this is dependent on what flexibility you actually need: what kind of objects do you want to pass to f and what do want to do with those objects?

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) {}
        };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM