What is the difference between the following?
List <?> list = (List<?>) var;
List <String> list = (List) var;
Essentially, the difference is that one makes your code type safe and one makes it type unsafe.
If you cast to a raw type, like (List)var, you are basically giving up the safety provided by generics. var could be a List<Integer>, and now that you have casted it, you can assign it to a List<String> without the compiler complaining. You can even get strings out of it (which should have been a List<Integer>) without the compiler complaining (but this will throw an exception at runtime). So casting to a raw type is like saying to the compiler:
I don't know exactly what type of list this will be right now, but I will do at runtime. I can hold all this type information of all these variables in my head all at once, so you don't need to worry about it! I'll handle types on my own.
...which is not a wise thing to do if the compiler can already do it for you. Humans tend to make errors.
Casting to a (bounded) wildcard is like saying to the compiler:
I don't know exactly what type of list this will be right now, but I will do at runtime. I can't hold all this type information of all these variables in my head all at once, so you have to give me an error whenever what I am doing might not succeed all the time, ok?
In this case, the compiler knows that you don't know the generic parameter and so disallows you to do certain things, like adding a String to a List<?>, because ? could be Integer. You can still get Objects out of a List<?> though, because whatever ? is, it has to be a subclass of Object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With