1. The implementation method of Java generics is erasure. The virtual machine will directly treat the generic type as Object type, and the compiler will safely cast the generic type

2. Covariant Java generics are non-covariant (a subclass’s generic type is not a subclass of a generic type) due to type erasing in Java, so you cannot assign a subclass’s generic type object to a parent class’s generic reference, such as

List<TextView> list = new ArrayList<Button>();
Copy the code

The compiler reports an error, which is not allowed, but now I have a requirement to get the text of all views in List

and print it as follows

private void printText(List<TextView> list) { for (TextView textView : list) { System.out.println(textView.getText()); }}Copy the code

GetText (); getText(); getText(); getText(); getText(); getText(); getText(); getText() Use the
upper bound wildcards, which modify the code to

private void printText(List<? extends TextView> list) { for (TextView textView : list) { System.out.println(textView.getText()); }}Copy the code

I can pass in List

So
the upper bound wildcard can be read but not written, as long as it satisfies certain covariant requirements. You can obtain its value but cannot modify it, except by adding null values

3. Contravariant is anti-covariant, and Java still cannot assign a parent generic type object to a subclass generic reference, such as

List<Button> list = new ArrayList<TextView>();
Copy the code

The compiler reported an error and I now have a method as follows

private void addText(List<Button> list) {
        list.add(new Button(this));
}
Copy the code

Now I can pass in a List

private void addText(List<? super Button> list) {
        list.add(new Button(this));
}
Copy the code

I can pass List

List or even List

List. But the question is, do I want to read the list in this method, and the answer is no, why? It’s a type safety question, Because the compiler doesn’t know if the List

List or even the List

List collection you passed holds a TextView or View, it doesn’t know the correct type when you fetch it



So
lower bound wildcard is writable and unreadable when it meets some inverter requirements, that is, you can modify it but cannot get its value

conclusion

Java’s generics are non-covariant due to type-safety issues caused by Java’s implementation of generics by erases, that is, subclass generics are not subclasses of parent generics, such as List