Here's a quick little generic class to make this question easier to understand. You can pretend it "boxes" a value if you want.
public class Box<T> { }
Question
Now, in my main
method, I can have this:
Box b1 = new Box<>();
Box<?> b2 = b1;
Box b3 = b2;
So it's quite clear to me that a raw Box
and a Box
parameterized with a wildcard can both be casted to each others' types.
Object box = (Box<?>)(Box) (Box<?>)(Box) ... new Box<>();// Valid (without the ellipsis)
So why is it that my List
of raw boxes can't be cast to a List
of wildcard boxes, and vice versa? (Any documentation that is responsible for the compiling error the following code raises, would do if you can find it.)
List<Box> rawBoxes = new LinkedList<>();
List<Box<?>> wildcardBoxes = new LinkedList<>();
Object o1 = (List<Box<?>>) rawBoxes;// Cannot cast from List<Box> to List<Box<?>>
Object o2 = (List<Box>) wildcardBoxes;// Cannot cast from List<Box<?>> to List<Box>
"Cannot cast from List<Box>
to List<Box<?>>
" and vice versa...
Before you answer/mark as dupe...
I'm guessing that someone is going to try and bring up the fact that a List<Dog>
can't be cast to a List<Animal>
and vice versa. The reason for that, however, is:
List<Animal> animals = new LinkedList<>();
animals.add(new Cat());
Dog dog = ((List<Dog>) animals).get(0);
A list of Dog
s is not a list of Animal
s, because it can only contain Dog
s.
With a List<Box>
and List<Box<?>>
, any sort of Box
can be put into either:
List<Box> rawBoxes = new LinkedList<>();
List<Box<?>> wildcardBoxes = new LinkedList<>();
Box rawBox = new Box<>();
Box<?> wildcardBox = new Box<>();
Box<String> stringBox = new Box<>();
// They can both take raw boxes
rawBoxes.add(rawBox);
wildcardBoxes.add(rawBox);
// They can both take wildcard boxes
rawBoxes.add(wildcardBox);
wildcardBoxes.add(wildcardBox);
// They can both take boxes storing arbitrary stuff
rawBoxes.add(stringBox);
wildcardBoxes.add(stringBox);
Lastly
This came up, which tells me that such a cast would be safe, if Java were to allow it. What I want to know is why a cast from List<Box>
to List<Box<?>>
isn't allowed and how to get a List<Box<?>>
off of a List<Box>
.
If there's another question that will thoroughly answer both of these things, please mark this as a duplicate. I didn't know exactly what to look up when searching for an answer myself.