关于? extends Fruit 和? super Fruit类上的使用
//? extends Fruit 只能读不能写,读出为Fruit及衍生类
List<? extends Fruit> fruits = Arrays.asList(new Apple());
//会报错不允许
//fruits.add(new Apple());
//正常执行
Fruit fruit = fruits.get(0);
Apple apple = (Apple) fruits.get(0);
//? super Fruit 能读能写,读出Object需要类型转换
List<? super Fruit> fruits1 = new ArrayList<>();
fruits1.add(new Fruit());
fruits1.add(new Apple());
Fruit fruit1= (Fruit) fruits1.get(0);
Food food1= (Food) fruits1.get(0);
Apple apple1= (Apple) fruits1.get(1);
//使用T extends 可以限定?extends
public class Test <T extends Fruit>{
public Test(T t2){
t = t2;
}
T t;
public T get(){
return t;
}
public void set(T t1){
t = t1;
}
}
Test<? super Fruit> tt = new Test<>(new Apple());
tt.set(new Apple());
Fruit fruit2 = (Fruit) tt.get();
做为参数使用注意事项:
-
参数写成:T<? super B>,对于这个泛型,?代表容器里的元素类型,由于只规定了元素必须是B的超类,导致元素没有明确统一的“根”(除了Object这个必然的根),所以这个泛型你其实无法使用它,对吧,除了把元素强制转成Object。所以,对把参数写成这样形态的函数,你函数体内,只能对这个泛型做插入操作,而无法读
-
参数写成: T<? extends B>,由于指定了B为所有元素的“根”,你任何时候都可以安全的用B来使用容器里的元素,但是插入有问题,由于供奉B为祖先的子树有很多,不同子树并不兼容,由于实参可能来自于任何一颗子树,所以你的插入很可能破坏函数实参,所以,对这种写法的形参,禁止做插入操作,只做读取
网友评论