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
toNumber
, but aList<
Integer
>
is not aList<
Number
>
- Similarly, a
List<Integer>
can be capture-converted by aList<?>
, but aList<
List<Integer>
>
is not aList<
List<?>
>
- Similarly, a
- Using bounded wildcard, a
List<? extends 
Number
>
can capture-convert aList<
Integer
>
- Similarly, a
List<? extends 
List<?>
>
can capture-convert aList<
List<Integer>
>
- Similarly, a
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
- Multiple wildcards on a generic methods makes Java compiler (and me!) very confused
- Very long and detailed exploration into this problem
- Java Generic
List<List<? extends Number>>
- Any simple way to explain why I cannot do
List<Animal> animals = new ArrayList<Dog>()
? - What is the difference between
<E extends Number>
and<Number>
?