栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java泛型类型擦除以及其局限性

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java泛型类型擦除以及其局限性

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

Java的泛型是伪泛型,Java的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程称为类型擦除。

如在代码中定义List和List等类型,在编译后都会变成List,JVM看到的只是List,而由泛型附加的类型信息对JVM是看不到的。Java编译器会在编译时尽可能的发现可能出错的地方,但是仍然无法在运行时刻出现的类型转换异常的情况,类型擦除也是Java的泛型与C++模板机制实现方式之间的重要区别。
例子:

public class fanxing {
    public static void main(String[] args) throws Exception {
        ArrayList list = new ArrayList();
        list.add("abc");
        Class cla = list.getClass();
        Method method = cla.getMethod("add", Object.class);
        method.invoke(list,123);
        System.out.println(list);
    }
}

输出:

[abc, 123]

这里发现定义泛型为String类型,但是通过反射机制,可以将数字123插入list中,我们利用反射调用add方法的时候,可以存储数字。这说明了String泛型实例在编译之后被擦除了,只保留了原始类型

当我们打印list的时候会发现报错

public class fanxing {
    public static void main(String[] args) throws Exception {
        ArrayList list = new ArrayList();
        list.add("abc");
        Class cla = list.getClass();
        Method method = cla.getMethod("add", Object.class);
        method.invoke(list,123);
        System.out.println(list);

        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }
}

输出

[abc, 123]
abc
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
	at com.leetcode.testAPI.fanxing.main(fanxing.java:16)

发现这里打印日志的时候会报错,因为输出的list的泛型是String,123不能被打印出来。
原始类型
原始类型 就是擦除去了泛型信息,最后在字节码中的类型变量的真正类型,无论何时定义一个泛型,相应的原始类型都会被自动提供,类型变量擦除,并使用其限定类型(无限定的变量用Object)替换。

类型擦除局限性 1、不能使用instanceof
List list = new ArrayList<>();
System.out.println(list instanceof ArrayList);

类型擦除后String类型不存在了,所以不能使用instanceof判断

2、不能用基本类型实例化类型参数

不能用类型参数代替基本类型。因此, 没有 Pair, 只 有 Pair。 当然,其原因是类型擦除。擦除之后, Pair 类含有 Object 类型的域, 而 Object 不能存储 int值。

3、不能创建参数化类型的数组 4、泛型类的静态上下文中类型变量无效

不能在静态域或方法中引用类型变量

5、不能抛出或捕获泛型类的实例
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/865838.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号