How do generics of generics work?

There is no potential runtime error, it's just outside the compiler's ability to statically determine that. Whenever you cause a type inference it automatically generates a new capture of <? extends Number>, and two captures are not considered equivalent.

Hence if you remove the inference from the invocation of singletonList by specifying <T> for it:

List<Test<? extends Number>> l = Collections.<Test<? extends Number>>singletonList(t);

It works fine. The generated code is no different than if your call had been legal, it's just a limitation of the compiler that it can't figure that out on its own.

The rule that an inference creates a capture and captures aren't compatible is what stops this tutorial example from compiling and then blowing up at runtime:

public static void swap(List<? extends Number> l1, List<? extends Number> l2) {
    Number num = l1.get(0);
    l1.add(0, l2.get(0));
    l2.add(0, num);

Yes the language specification and compiler probably could be made more sophisticated to tell your example apart from that, but it's not and it's simple enough to work around.


Maybe this can explain the problem of the compiler:

List<? extends Number> myNums = new ArrayList<Integer>();

This genric wildcard list can hold any elements extending from Number. So its OK to assign an Integer list to it. However now I could add a Double to myNums because Double is also extending from Number which would lead to a runtime problem. So the compiler forbids every write access to myNums and I can only use read methods on it, because I only know what ever I get can be cast to Number.

And so the compiler is complaining about a lot of things you can do with such a wildcard generic. Sometimes he is mad about things which you can ensure they are safe and OK.

But luckily there is a trick to get around this error so you can test on your own what can maybe break this:

public static void main(String[] args) {

    List<? extends Number> list1 = new ArrayList<BigDecimal>();
    List<List<? extends Number>> list2 = copyHelper(list1);


private static <T> List<List<T>> copyHelper(List<T> list) {
    return Collections.singletonList(list);


The reason is that the compiler doesn't know that your wildcard types are the same type.

It also doesn't know that your instance is null. Although null is a member of all types, the compiler considers only declared types, not what the value of the variable might contain, when type checking.

If the code executed, it wouldn't cause an exception, but that's only because the value is null. There is still a potential type mismatch, and that's what the compiler's job is - to disallow type mismatches.


My android app needs communicate with server when it's (application) opened. For that I want to use socketIO Java client. Do I need to use BoundService for sockets (it should run on background)? ...

I was poking around the rabbitmq documentation, and it seems that rabbitmq does not handle message redelivery count. If I were to manually ACK/NACK messages, I would need to either keep the retry ...

I'm not a Java guy but use Solr for searching, but after search about this issue I couldn't find out why it is happening. I have a 30-million-records-index with no sorting and the lightest setup I ...

The code identifies the integer that is closest to 0 in an array and if there are 2 or more values that meet this condition the return value should be null.The problem is that when I make the ...