【Java 你应该知道的】泛型02

泛型的类型擦除

        所谓类型擦除,是指在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。也就是说,泛型只在编译过程有效,成功编译过后的class文件中是不包含任何泛型信息的,从而泛型信息不会进入到运行时阶段。看下面的例子:

    List list1 = new ArrayList<>();
    List list2 = new ArrayList<>();
    System.out.println(list1.getClass() == list2.getClass());

        返回结果为true,原因在于编译时ListList 的类型都被擦除了,编译后只有List类型。
        再看一个小例子,定义Box的泛型类:

    public class Box {
        private T t;
        public Box(T t) {
            super();
            this.t = t;     
        }
    }
    Box box = new Box("abc");
    box instanceof Box //编译不通过,因为String类型被擦除
    box instanceof Box //编译通过,返回true


通配符

        在使用泛型类的时候,既可以指定一个具体的类型,如List就声明了具体的类型是String。也可以用通配符?来表示未知类型,如List就声明了List中包含的元素类型是未知的。

        但是List并不等同于ListList实际上确定了List中包含的是Object及其子类,在使用的时候必须通过Object来进行引用。而List则其中所包含的元素类型是不确定。

        看下面的小例子,封装一个方法,打印集合的所有信息。

    public static void main(String[] args) {
        List list = new ArrayList<>();
        list.add("abc");
        showList(list); //编译错误
    }
    
    private static void showList(List list) {
        for (Object obj : list) {
            System.out.println(obj.toString());
        }
    }
 
 

        修改如下,将showList方法参数的List改成List即可。

    public static void main(String[] args) {
        List list = new ArrayList<>();
        list.add("abc");
        showList(list); //编译通过
    }
    
    private static void showList(List list) {
        for (Object obj : list) {
            System.out.println(obj.toString());
        }
    }

通配符上下限

  • 通配符 ?:可以接收任意引用类型
  • 上限 ?extends E:可以接收E类型或者E的子类型
  • 下限 ?super E:可以接收E类型或者E的父类型
【Java 你应该知道的】泛型02_第1张图片
点滴分享 共同进步


你可能感兴趣的:(【Java 你应该知道的】泛型02)