通过与 Jira 对比,让您更全面了解 PingCode

  • 首页
  • 需求与产品管理
  • 项目管理
  • 测试与缺陷管理
  • 知识管理
  • 效能度量
        • 更多产品

          客户为中心的产品管理工具

          专业的软件研发项目管理工具

          简单易用的团队知识库管理

          可量化的研发效能度量工具

          测试用例维护与计划执行

          以团队为中心的协作沟通

          研发工作流自动化工具

          账号认证与安全管理工具

          Why PingCode
          为什么选择 PingCode ?

          6000+企业信赖之选,为研发团队降本增效

        • 行业解决方案
          先进制造(即将上线)
        • 解决方案1
        • 解决方案2
  • Jira替代方案

25人以下免费

目录

泛型擦除是什么,会带来什么问题

Java 的泛型是伪泛型,这是因为 Java 在运行期间,所有的泛型信息都会被擦掉,这也就是通常所说类型擦除。Java 泛型(generics) 是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制。

一、泛型擦除

泛型擦除介绍

Java 的泛型是伪泛型,这是因为 Java 在运行期间,所有的泛型信息都会被擦掉,这也就是通常所说类型擦除。Java 泛型(generics) 是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制。该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

List<Integer> list = new ArrayList<>();

list.add(12);

//这里直接添加会报错

list.add(“a”);

Class<? extends List> clazz = list.getClass();

Method add = clazz.getDeclaredMethod(“add”, Object.class);

//但是通过反射添加是可以的

//这就说明在运行期间所有的泛型信息都会被擦掉

add.invoke(list, “kl”);

System.out.println(list);

带来什么样的问题

(1) 强制类型转化

这个问题的结果我们已经在上述文章中提及到了,通过反射的方式去进行插入的时候,我们的数据就会发生错误。

如果我们在一个List<Integer>中在不知情的情况下插入了一个String类型的数值,那这种重大错误,我们该找谁去说呢。

(2)引用传递问题

上面的问题中,我们已经说过了T将在后期被转义成Object,那我们对引用也进行一个转化,是否行得通呢?

List<String> listObject = new ArrayList<Object>();

List<Object> listObject = new ArrayList<String>();

如果你这样写,在我们的检查阶段,会报错。但是从逻辑意义上来说,其实你真的有错吗?

假设说我们的名列前茅种方案是正确的,那么其实就是将一堆Object数据存入,然后再由上面所说的强制转化一般,转化成String类型,听起来完全ok,因为在List中本来存储数据的方式就是Object。但其实是会出现ClassCastException的问题,因为Object是万物的基类,但是强转是为子类向父类准备的措施。

再来假设说我们的第二种方案是正确的,这个时候,根据上方的数据String存入,但是有什么意义存在呢?最后都还是要成Object的,你还不如就直接是Object。

延伸阅读:

二、继承型的用处是什么

其实他期待的就是这整个列表的数据的基础都是来自我们的Parent,这样获取的数据全部人的父类其实都是来自于我们的Parent了,你可以叫这个列表为Parent家族。所以也可以说这是一个适合频繁读取的方案。

Plate<? extends Fruit> p1=new Plate<Apple>(new Apple());

Plate<? extends Fruit> p2=new Plate<Apple>(new Beef()); // 检查不通过

// 修改数据不通过

p1.set(new Banana());

// 数据获取一切正常

// 但是他只能精确到由我们定义的Fruit

Fruit result = p1.get();

<T super Parent>

相关文章