Let's first consider a simple scenario ([see complete source on ideone.com](http://ideone.com/jXOh0)):

```
import java.util.*;

public class TwoListsOfUnknowns {
    static void doNothing(List<?> list1, List<?> list2) { }

    public static void main(String[] args) {
        List<String> list1 = null;
        List<Integer> list2 = null;
        doNothing(list1, list2); // compiles fine!
    }
}

```

The two wildcards are unrelated, which is why you can call `doNothing` with a `List<String>` and a `List<Integer>`. In other words, the two `?` can refer to entirely different types. Hence the following does not compile, which is to be expected ([also on ideone.com](http://ideone.com/moqSj)):

```
import java.util.*;

public class TwoListsOfUnknowns2 {
    static void doSomethingIllegal(List<?> list1, List<?> list2) {
        list1.addAll(list2); // DOES NOT COMPILE!!!
            // The method addAll(Collection<? extends capture#1-of ?>)
            // in the type List<capture#1-of ?> is not applicable for
            // the arguments (List<capture#2-of ?>)
    }
}

```

So far so good, but here's where things start to get very confusing ([as seen on ideone.com](http://ideone.com/YIy6Q)):

```
import java.util.*;

public class LOLUnknowns1 {
    static void probablyIllegal(List<List<?>> lol, List<?> list) {
        lol.add(list); // this compiles!! how come???
    }
}

```

The above code compiles for me in Eclipse and on `sun-jdk-1.6.0.17` in ideone.com, but should it? Is it not possible that we have a `List<List<Integer>> lol` and a `List<String> list`, the analogous two unrelated wildcards situations from `TwoListsOfUnknowns`?

In fact the following slight modification towards that direction does not compile, which is to be expected ([as seen on ideone.com](http://ideone.com/aS8WP)):

```
import java.util.*;

public class LOLUnknowns2 {
    static void rightfullyIllegal(
            List<List<? extends Number>> lol, List<?> list) {

        lol.add(list); // DOES NOT COMPILE! As expected!!!
            // The method add(List<? extends Number>) in the type
            // List<List<? extends Number>> is not applicable for
            // the arguments (List<capture#1-of ?>)
    }
}

```

So it looks like the compiler is doing its job, but then we get this ([as seen on ideone.com](http://ideone.com/A8dPb)):

```
import java.util.*;

public class LOLUnknowns3 {
    static void probablyIllegalAgain(
            List<List<? extends Number>> lol, List<? extends Number> list) {

        lol.add(list); // compiles fine!!! how come???
    }
}

```

Again, we may have e.g. a `List<List<Integer>> lol` and a `List<Float> list`, so this shouldn't compile, right?

In fact, let's go back to the simpler `LOLUnknowns1` (two unbounded wildcards) and try to see if we can in fact invoke `probablyIllegal` in any way. Let's try the "easy" case first and choose the same type for the two wildcards ([as seen on ideone.com](http://ideone.com/PzN9N)):

```
import java.util.*;

public class LOLUnknowns1a {
    static void probablyIllegal(List<List<?>> lol, List<?> list) {
        lol.add(list); // this compiles!! how come???
    }

    public static void main(String[] args) {
        List<List<String>> lol = null;
        List<String> list = null;
        probablyIllegal(lol, list); // DOES NOT COMPILE!!
            // The method probablyIllegal(List<List<?>>, List<?>)
            // in the type LOLUnknowns1a is not applicable for the
            // arguments (List<List<String>>, List<String>)
    }
}

```

This makes no sense! Here we aren't even trying to use two different types, and it doesn't compile! Making it a `List<List<Integer>> lol` and `List<String> list` also gives a similar compilation error! In fact, from my experimentation, the only way that the code compiles is if the first argument is an explicit `null` type ([as seen on ideone.com](http://ideone.com/OYVEY)):

```
import java.util.*;

public class LOLUnknowns1b {
    static void probablyIllegal(List<List<?>> lol, List<?> list) {
        lol.add(list); // this compiles!! how come???
    }

    public static void main(String[] args) {
        List<String> list = null;
        probablyIllegal(null, list); // compiles fine!
            // throws NullPointerException at run-time
    }
}

```

So the questions are, with regards to `LOLUnknowns1`, `LOLUnknowns1a` and `LOLUnknowns1b`:

* What types of arguments does `probablyIllegal` accept?
* Should `lol.add(list);` compile at all? Is it typesafe?
* Is this a compiler bug or am I misunderstanding the capture conversion rules for wildcards?

---

### Appendix A: Double LOL?

In case anyone is curious, this compiles fine ([as seen on ideone.com](http://ideone.com/U65yx)):

```
import java.util.*;

public class DoubleLOL {
    static void omg2xLOL(List<List<?>> lol1, List<List<?>> lol2) {
        // compiles just fine!!!
        lol1.addAll(lol2);
        lol2.addAll(lol1);
    }
}

```

---

### Appendix B: Nested wildcards -- what do they really mean???

Further investigation indicates that perhaps multiple wildcards has nothing to do with the problem, but rather a *nested* wildcard is the source of the confusion.

```
import java.util.*;

public class IntoTheWild {

    public static void main(String[] args) {
        List<?> list = new ArrayList<String>(); // compiles fine!

        List<List<?>> lol = new ArrayList<List<String>>(); // DOES NOT COMPILE!!!
            // Type mismatch: cannot convert from
            // ArrayList<List<String>> to List<List<?>>
    }
}

```

So it looks perhaps a `List<List<String>>` is not a `List<List<?>>`. In fact, while any `List<E>` is a `List<?>`, it doesn't look like any `List<List<E>>` is a `List<List<?>>` ([as seen on ideone.com](http://ideone.com/XLoGE)):

```
import java.util.*;

public class IntoTheWild2 {
    static <E> List<?> makeItWild(List<E> list) {
        return list; // compiles fine!
    }
    static <E> List<List<?>> makeItWildLOL(List<List<E>> lol) {
        return lol;  // DOES NOT COMPILE!!!
            // Type mismatch: cannot convert from
            // List<List<E>> to List<List<?>>
    }
}

```

A new question arises, then: just what is a `List<List<?>>`?