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 T
s you can pass in are null
), and ? super
to signify write-only (since you can only get out T
s as Object
). This isn't completely fool-proof (you can still call remove methods, pass in null
s, 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. String
s 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