简体   繁体   中英

Unchecked cast between wildcard generic type and generic type

please help me to understand why this cast is unchecked:

 List<? extends String> t= ...;
 List<String> t2=(List<String>)t;

It should be totally safe... I think this has probably already been asked, but I can't find it... too many questions about generics! I use regularly generics, but this doubt has always been there... Thank you in advance.

Edit: As pointed out, I should have used a non final class. So:

List<? extends ConfigurationAdapter> t= new ArrayList<DATASOURCE_ConfigurationAdapter>();
List<ConfigurationAdapter> t2=(List<ConfigurationAdapter>)t;

This works. I can't understand why it's unchecked.

I suppose an example can explain the reason of the warning.

But let's use other type, since strings cannot actually have subtypes in Java.

List<Integer> integers = new ArrayList<>(asList(1,2,3,4,5));
List<? extends Number> anyNumbers = integers;

Now, suppose we force the cast that you are doing, imagine that you could even do it without a warning

List<Number> numbers = (List<Number>) anyNumbers;

Now, you could do this:

numbers.add(3.5);

And later, in some other place in your code, somebody is trying to use the original collection like this:

for(Integer myInt: integers) { //ClassCastException

}

You get a ClassCastException because you have now broken the expectations of the type system. The original collection should accept Integers only, but you have managed to fool Java to make it accept any kind of numbers, in this case a double. Of course, when you iterate over the original collection, expecting integers, when you find one that is not actually an integer, your code will fail.

That's why it is logical that the compiler throws a warning, and that's why it is dangerous not to listen to it. And the fact that the String is a final class in Java is the reason why in your particular case you won't probably find any scenarios that finish in this problem I just described. But for other cases, this is a likely possibility.

For String it is totally safe and you can ignore the warning. The same would go for any type bound where the type is a final class type.

For any other type, the type of the value assigned to t might be a List<SubtypeOfTheBound> . In which case, it could not be assigned to a List<Bound> .

More reading:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM