一:JAVA泛型的协变
简而言之,协变就是,如果A是B的子类,那么Generic<A>就是Generic<? extends B>的子类型。
协变指的是,当参数具有父子关系时,子类可以作为参数传递,而泛型的上界就是其父类。
JAVA泛型的协变通过上界通配符<? extends 父类型>
-
「?」通配符表示这是一个未知类型
-
「extends」上界通配符表示这个类型只能是其子类或者本身 Button TextView
上界通配符还有一个特例,那就是「?」,例如List<?>,实际上就是List<? extends Object>的缩写。在Kotlin中,使用的是「*」,即List<*>,实际上就是List<out Any>
二:JAVA泛型的协变的限制:泛型类型只能对外提供数据,不能写入数据
List<? extends TextView>的类型定义是<? extends TextView>,编译器并不知道这个元素 textViews.get(0)具体是什么类型(可能是TextView及其子类),所以这个元素不能添加到List集合里
List<? extends TextView> textViews = new ArrayList<TextView>();
TextView textView = textViews.get(0);
// Error 泛型集合List 并不知道元素textViews.get(0)是什么具体类型所以不能添加到泛型集合里去
textViews.add(textView);
三:JAVA泛型的逆变
简而言之,逆变就是,如果A是B的子类,那么Generic<B>就是Generic<? super A>的子类型。
逆变指的是,父类可以作为参数传递,但子类必须是其下界。
JAVA泛型的逆变通过下界通配符<? super 子类型>来实现。
-
「?」通配符表示这是一个未知类型
-
「super」下界通配符表示后面的这个类型,只能是它子类或者本身
四:JAVA泛型的逆变的限制
不能读指的是不能读取为指定的类型,而不是不能调用读的方法。