madtyn
madtyn

Reputation: 1549

Why this Java generic code with bounded wildcard doesn't compile?

I was reading the superb Java Generics FAQ by Angelika Langer when I read this source code example which I can't understand:

import java.util.List;
import java.util.ArrayList;
import java.lang.Number;
import java.lang.String;
import java.lang.Long;

class X<T extends List<? extends Number>> {
    public void someMethod(T t) {
        t.add(new Long(0L));    // error
        Number n = t.remove(0);
    }
}

I can't understand why the compiler can't infer that "Long extends Number" and match this with "? extends Number" before type erasure, making <? extends Number> completely useless.

I already read the FAQ, so I'm looking for a simpler explanation as well as for alternatives, please.

Thanks in advance

Upvotes: 2

Views: 94

Answers (1)

Eran
Eran

Reputation: 393801

Suppose someone uses your class this way:

List<Double> list = new ArrayList<>();
X<List<Double>> x = new X<>();
x.someMethod(list);

Now your method will try to add a Long to a List<Double>. That's why the compiler won't allow it.

You cannot add a Long to a List<? extends Number>, since a List<? extends Number> can be assigned a List<Double>, a List<Integer>, etc...

You can change your class declaration to X<T extends List<Number>>, which will solve the compilation error, since to a List<Number> you can always add a Long (or an instance of any other sub-class of Number).

Upvotes: 2

Related Questions