Why does Java doesn't throw any warning when compiling my TestGenerics class, considering that the String class is final and cannot be extended?
import java.util.*;
public class TestGenerics {
public void addStrings(List<? extends String> list) {
// some code here
}
}
}
Let's say I had a method like this:
public List<? extends T> filterOutNulls(List<T> input) { ...
Granted, not the best signature in the world, but still perfectly legal. What would happen if I passed a List<String> to that method? According to the signature, it returns a List<? extends String>. If Java disallowed that type, it'd be impossible to use this method for List<String> (or at least, it'd be impossible to use the return value).
Secondarily, the extends syntax is still useful in this case, since List<String> and List<? extends String> have different restrictions -- specifically, you can't add anything but a null literal to List<? extends String>. I'll sometimes use ? extends to signify that a collection is read-only (since the only Ts you can pass in are null), and ? super to signify write-only (since you can only get out Ts as Object). This isn't completely fool-proof (you can still call remove methods, pass in nulls, downcast, etc) but serves as a gentle reminder of how the collection is probably meant to be used.
The compiler doesn't really take note of that fact, because it doesn't matter. Strings are still allowed in the list, and in the final product, the possibility of anything extending String is not found. After erasure, it comes out like this:
public void addStrings(List list)
As you can see, there is now no suggestions of a class extending String. If you do create a class extending String, that will be itself a compile error. There's no need for javac to worry about that.
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