Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generics weird behaviour

Tags:

java

generics

It's hard to explain in words, but Java Generics are given me an unexpected result. I expected that if I say a list is of type ? extends Object, I could store anything in there. Therefore, if the list of of type Wrapper<? extends Object>, I could store any kind of Wrapper in there. And so on. That makes sense to me. But let's assume we have:

private static class Wrapper<T> {
    public Wrapper(T t) { /**/ }
}

And I want something like:

private static final List<Wrapper<Wrapper<? extends Object>>> ls1 = new ArrayList<>();

Note that this gives me an error:

public static <T> doit(T t) {
    Wrapper<Wrapper<T>> l1 = new Wrapper<>(new Wrapper<>(t));
    ls1.add(l1); // nok
    // add (Wrapper<Wrapper<? extends java.lang.Object>>) in List
    // cannot be applied to (Wrapper<Wrapper<T>>
}

But if I wrap the Wrapper in a secondary Wrapper (rs), then:

private static class C<T> extends Wrapper<Wrapper<T>> {
    public C(T t) {
        super(new Wrapper<>(t));
    }
}

private static final List<C<? extends Object>> ls2 = new ArrayList<>();

public static <T> doit(T t) {
    ls2.add(new C<>(t)); // ok
}

Note that it is the same thing; this make no sense to me.

PS. In my case, I'm not making a wrapper wrapper, but a ThreadLocal of a generic class.

like image 254
Luan Nico Avatar asked Oct 28 '16 12:10

Luan Nico


1 Answers

I think

? extends Object ---> equals ?

You can do like this

List<Wrapper<Wrapper<?>>> ls1 = new ArrayList<>();

And

Wrapper<Wrapper<?>> l1 = new Wrapper<>(new Wrapper<>(t));
ls1.add(l1); // OK
like image 164
Loc Avatar answered Oct 27 '22 22:10

Loc