关于泛型类型通配符的小知识点

  • 对于类型通配符
import java.util.ArrayList;
import java.util.List;

class Fruit{}
class Apple extends Fruit{}
class Orange extends Fruit{}

public class Main {
  public static void main(String[] args) {
    List fruits;
    List apples = new ArrayList<>();
    List oranges = new ArrayList<>();
    apples.add(new Apple());

    oranges.add(new Apple());       //编译错误
    fruits = oranges;

      /*这和上一个注释掉的语句作用相同,因此这里List fruits不能添加Apple对象*/
    fruits.add(new Apple());          //编译错误
      
      /*这和上上一个注释掉的语句作用相同,因此这里List fruits甚至不能添加Object对象*/
    fruits.add((Object)new Apple());      //编译错误
      
      /*任何参数里涉及泛型的函数由于安全问题都无法正常使用,get方法没有泛型,返回时Object,因此可以正常使用*/
    fruits.get(1);      
  }
}

对于`List fruits,应当将其解读为

具有任何从Fruit继承的类型的列表

而不应该是

这个List将持有任何类型的Fruit

  • 对于超类型通配符
import java.util.ArrayList;
import java.util.List;

class Fruit{}
class Apple extends Fruit{}
class Orange extends Fruit{}
class Jonathan extends Apple{}

public class Main2 {

  public static void main(String[] args) {
    
    List fruits;
    List apples = new ArrayList();
    fruits = apples;
    
    /*fruits 的基类是Apple,因此可以添加任何Apple类型及其子类,无法添加Object */
    fruits.add(new Apple());
    fruits.add(new Jonathan());
    list1.add(new Object());    //编译错误
    
    /*get函数正常,原理相同*/
    fruits.get(1);
  }
}


  • 总结

    出于类型安全考虑

    • 对于List apple,不能使用add()方法添加任何对象
    • 对于List apples,可以使用add()方法添加Apple对象及其子类对象

参考资料:Java编程思想 P390-P393

如有错误还请指正

你可能感兴趣的:(关于泛型类型通配符的小知识点)