PFiver
PFiver

Reputation: 249

Java generics wildcards: Why does this not compile?

class Demo {
    <T> void gTee(List<List<T>> tl) {
        tee(tl);
    }

    void tee(List<List<?>> tl) {
    }
}

JDK 8 says

incompatible types: java.util.List<java.util.List<T>> cannot be converted to java.util.List<java.util.List<?>>

How come? I was of the opinion that the ? wildcard stands for any type.

Upvotes: 4

Views: 106

Answers (2)

PFiver
PFiver

Reputation: 249

Ah. Holy cube. I should have known but it did not come to my mind:

enter image description here

https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Use-site_variance_annotations_.28wildcards.29

It compiles now:

class Demo {
    <T> void gTee(List<List<T>> tl) {
        tee(tl);
    }

    void tee(List<? extends List<?>> tl) {
    }
}

Upvotes: 4

Sweeper
Sweeper

Reputation: 270850

This is due to this behaviour of Java generics:

Even if A and B are compatible types, SomeType<A> is not compatible with SomeType<B>

A classic example of this is trying to assign a List<Cat> to a List<Animal>.

The same thing happens here. Normally, List<T> can be assigned to List<?>. But since you are assigning List<List<T>> to List<List<?>>, you can't.

Upvotes: 4

Related Questions