下面展示一些 内联代码片
。
public class Test_2 {
public static void main(String[] args) {
List<? extends B> list1 = new ArrayList<>(); // 上界
List<? super B> list2 = new ArrayList<>(); // 下界
A a = new A();
B b = new B();
C c = new C();
Object o = new Object();
// list1.add(o); 不能添加任何元素,因为List中具体是B的哪种子类无法确定
// list1.add(a);
// list1.add(b);
// list1.add(c);
o = list1.get(0);
a = list1.get(0);
b = list1.get(0);
// c = list1.get(0); 编译错误,编译器无法向下转型
// list2.add(o); 编译错误,
// list2.add(a); 因为List中具体是B的哪种父类无法确定
list2.add(b);
list2.add(c);
o = list2.get(0);
// a = list2.get(0); 编译错误,因为List中具体是B的哪种父类无法确定,无法向下转型,而Object是所有类的父类
// b = list2.get(0);
// c = list2.get(0);
}
}
class A {}
class B extends A {}
class C extends B {}
上界
1.上界用 extends关键字声明,表示参数化的类型可能是所指定的类或者其任意子类。例如<? extends B>,泛型的上界就是 B 类。
2.形如 List<? extends B>,具体哪一种不能确定,既可以是 B,也可以是 C。在尝试执行 add() 方法时,List中的类型不能确定是具体哪一种,所以会编译报错。在执行 get() 方法时,不管是 B 还是 C,都可以以 A 类对象来接收。所以 List<? extends B> 不能添加元素,具有只读属性,只能获取。
下界
1.下界用 super 关键字声明,表示参数化的类型可能是所指定的类型或者其任意父类。例如<? super B>,泛型的下界就是 B 类。
2.形如 List<? super B>,具体哪一种不能确定,既可以是 B,也可以是 A,直至 Object类。在尝试执行 add() 方法时,虽然 List 的具体类型不能确定,但是根据多态, B 类及其子类的对象肯定都可以被赋值给 B 的对象,所以只能添加 B 类及其子类的对象。在尝试执行 get() 方法时,List 中的类型是 B 类或者其父类的具体一种,向上直至 Object 类,所以只能将获取的元素赋值给 Object 对象。