Can’t cast to to unspecific nested type with generics

Use the following:

Msg<? extends Value<?>> someMsg = strMsg;

The problem is that the ? in Msg<Value<?>> objMsg is NOT capable of capture conversion. It’s not “a Msg of Value of some type. It’s “a Msg of Value of ANY type”.

This also explains why along with the declaration change, I’ve also renamed the variable to someMsg. The Value can’t just be any Object. It must belong to some type (String in this example).


A more generic example

Let’s consider a more generic example of a List<List<?>>. Analogously to the original scenario, a List<List<?>> can NOT capture-convert a List<List<Integer>>.

    List<List<Integer>> lolInt = null;

    List<List<?>> lolAnything = lolInt;         // DOES NOT COMPILE!!!
    // a list of "lists of anything"

    List<? extends List<?>> lolSomething = lolInt;   // compiles fine!
    // a list of "lists of something"

Here’s another way to look at it:

  • Java generics is type invariant
  • There’s a conversion from Integer to Number, but a List<Integer> is not a List<Number>
    • Similarly, a List<Integer> can be capture-converted by a List<?>, but a List<List<Integer>> is not a List<List<?>>
  • Using bounded wildcard, a List<? extends Number> can capture-convert a List<Integer>
    • Similarly, a List<? extends List<?>> can capture-convert a List<List<Integer>>

The fact that some ? can capture and others can’t also explains the following snippet:

    List<List<?>> lolAnything = new ArrayList<List<?>>(); // compiles fine!

    List<?> listSomething = new ArrayList<?>(); // DOES NOT COMPILE!!!
        // cannot instantiate wildcard type with new!

Related questions

See also

Leave a Comment