专栏首页程序那些事类型擦除type erasure

类型擦除type erasure

简介

泛型是java从JDK 5开始引入的新特性,泛型的引入可以让我们在代码编译的时候就强制检查传入的类型,从而提升了程序的健壮度。

泛型可以用在类和接口上,在集合类中非常常见。本文将会讲解泛型导致的类型擦除。

举个例子

我们先举一个最简单的例子:

@Slf4j
public class TypeErase {

    public static void main(String[] args) {
        ArrayList<String> stringArrayList = new ArrayList<String>();
        stringArrayList.add("a");
        stringArrayList.add("b");
        action(stringArrayList);
    }

    public static void action(ArrayList<Object> al){
        for(Object o: al)
            log.info("{}",o);
    }}

上面的例子中,我们定义了一个ArrayList,其中指定的类型是String。

然后调用了action方法,action方法需要传入一个ArrayList,但是这个list的类型是Object。

乍看之下好像没有问题,因为String是Object的子类,是可以进行转换的。

但是实际上代码编译出错:

Error:(18, 16) java: 不兼容的类型: java.util.ArrayList<java.lang.String>无法转换为java.util.ArrayList<java.lang.Object>

原因

上面例子的原因就是类型擦除(type erasure)。java中的泛型是在编译时做检测的。而编译后生成的二进制文件中并不保存类型相关的信息。

上面的例子中,编译之后不管是ArrayList<String> 还是ArrayList<Object> 都会变成ArrayList。其中的类型Object/String对JVM是不可见的。

但是在编译的过程中,编译器发现了两者的类型不同,然后抛出了错误。

解决办法

要解决上面的问题,我们可以使用下面的办法:

   public static void actionTwo(ArrayList<?> al){
        for(Object o: al)
            log.info("{}",o);
    }

通过使用通配符?,可以匹配任何类型,从而通过编译。

但是要注意这里actionTwo方法中,因为我们不知道传入的类型到底是什么,所以我们不能在actionTwo中添加任何元素。

总结

从上面的例子我们可以看出,ArrayList<String>并不是ArrayList<Object>的子类。如果一定要找出父子关系,那么ArrayList<String>是Collection<String>的子类。

但是Object[] objArray是String[] strArr的父类。因为对Array来说,其具体的类型是已知的。

本文分享自微信公众号 - 程序那些事(flydean-tech),作者:flydean

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-05-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一文弄懂String的所有小秘密

    String是java中非常常用的一个对象类型。可以说java中使用最多的就是String了。

    程序那些事
  • JVM系列之:String.intern和stringTable

    StringTable是什么?它和String.intern有什么关系呢?在字符串对象的创建过程中,StringTable有起到了什么作用呢?

    程序那些事
  • Lambda表达式最佳实践

    Lambda表达式java 8引入的函数式编程框架。之前的文章中我们也讲过Lambda表达式的基本用法。

    程序那些事
  • 2.JAVA-基础语法以及String的介绍

    目前java中,和C/C++有点区别,就是暂未用到goto const关键字.示例如下:

    张诺谦
  • 聊聊nacos config的publishConfig

    nacos-1.1.3/config/src/main/java/com/alibaba/nacos/config/server/controller/Conf...

    codecraft
  • 聊聊nacos config的publishConfig

    nacos-1.1.3/config/src/main/java/com/alibaba/nacos/config/server/controller/Conf...

    codecraft
  • 实现在 Eclipse 中编写 Markdown 文件

    实现在 Eclipse 中编写 Markdown 文件 摘要: 本文介绍了使用 Eclipse Markdown Editor 插件,来实现在 Eclips...

    林老师带你学编程
  • 微服务[学成在线] day08:FastDFS 实现课程图片管理

    FastDFS是用c语言编写的一款开源的分布式文件系统,它是由淘宝资深架构师余庆编写并开源。FastDFS专为互联网量身定制,充分考虑了冗余备份、负载均衡、线性...

    LCyee
  • .net中的认证(authentication)与授权(authorization)

    注:这篇文章主要给新手看的,老手们可能会觉得没啥营养,就请绕过吧。 “认证”与“授权”是几乎所有系统中都会涉及的概念,通俗点讲: 认证(authenticat...

    菩提树下的杨过
  • 聊聊nacos config的deleteConfig

    nacos-1.1.3/config/src/main/java/com/alibaba/nacos/config/server/controller/Conf...

    codecraft

扫码关注云+社区

领取腾讯云代金券