java 泛型没有协变类型, 所以要重用extends, 但使用List 可以是ArrayList()、ArrayList()、ArrayList(), 因此不能add元素进去

时间:2023-03-09 03:07:44
java 泛型没有协变类型, 所以要重用extends, 但使用List<? extends Fruit> 可以是ArrayList<Fruit>()、ArrayList<Apple>()、ArrayList<Orange>(), 因此不能add元素进去
 class Fruit{}
class Apple extends Fruit{}
class SubApple extends Apple{}
class Orange extends Fruit{} class Holder<T>{
private T value;
public Holder(){}
public Holder(T value){this.value = value;}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public boolean equals (Object obj){
return value.equals(obj);
} }
public class CovarianArrays { public static void main(String[] args) {
Fruit [] fruitArray = new Apple[10];
fruitArray[0] = new SubApple();
//数组有协变类型,能放入SubApple
//编译时正常。运行时错误 ArrayStoreException 数组在运行时检查类型
//fruitArray[0] = new Fruit();
//fruitArray[1] = new Orange(); //编译时就出错
//List<Fruit> fruitList = new ArrayList<Apple>(); List<Apple> fruitList = new ArrayList<Apple>();
fruitList.add(new Apple());
//只能是Apple,泛型没有协变类型
//fruitList.add(new SubApple()); List<? extends Fruit> fruitExtendList = new ArrayList<Apple>();
//连Object都不行,只能是无意义的null
//fruitExtendList.add(new Apple());
//fruitExtendList.add(new Object());
fruitExtendList.add(null); List<? extends Fruit> fruitAsList = Arrays.asList(new Apple());
Apple a = (Apple) fruitAsList.get(0);
//以下两个方法的参数都是Object
fruitAsList.contains(new Apple());
int i =fruitAsList.indexOf(new Apple());
System.out.println(i);//-1 不存在 List<? super Apple> supList = new ArrayList<Apple>();
supList.add(new Apple());
supList.add(new SubApple());
//supList.add(new Fruit()); Holder<Apple> holdApple = new Holder<Apple>(new Apple());
Apple a1 = holdApple.getValue();
System.out.println(a1); //com.Array.Apple@10b30a7 //Holder<Fruit> holdFruit = holdApple;
Holder<? extends Fruit> holdFruit = holdApple;
Fruit f1 = holdFruit.getValue();
System.out.println(f1); //com.Array.Apple@10b30a7
Apple a2 = (Apple) holdFruit.getValue();
System.out.println(a2);
Orange o1 = (Orange) holdFruit.getValue(); //运行时出错ClassCastException
System.out.println(o1);
//不能调用setValue()
//holdFruit.setValue(new Orange()); } }

参考:

java 泛型没有协变类型, 所以要重用extends, 但使用List<? extends Fruit> 可以是ArrayList<Fruit>()、ArrayList<Apple>()、ArrayList<Orange>(), 因此不能add元素进去