文章目录

  • 简介
  • 举个例子
  • 原因
  • 解决办法
  • 总结

java中的类型擦除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来说,其具体的类型是已知的。

本文的例子https://github.com/ddean2009/learn-java-collections

更多精彩内容且看:

  • 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新
  • Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新
  • Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新
  • java程序员从小工到专家成神之路(2020版)-持续更新中,附详细文章教程

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/java-type-erasure/

本文来源:flydean的博客

欢迎关注我的公众号:程序那些事,更多精彩等着您!

java中的类型擦除type erasure相关推荐

  1. java 类型擦除_java中的类型擦除type erasure

    简介 泛型是java从JDK 5开始引入的新特性,泛型的引入可以让我们在代码编译的时候就强制检查传入的类型,从而提升了程序的健壮度. 泛型可以用在类和接口上,在集合类中非常常见.本文将会讲解泛型导致的 ...

  2. 泛型中的类型擦除和桥方法

    在Java中,泛型的引入是为了在编译时提供强类型检查和支持泛型编程.为了实现泛型,Java编译器应用类型擦除实现: 1.  用类型参数(type parameters)的限定(如果没有就用Object ...

  3. java 泛型和类型擦除_关于Java泛型和擦除

    java 泛型和类型擦除 "编译期间擦除泛型"是常识(好吧,类型参数和实参实际上是被擦除的). 这是由于"类型擦除"而发生的. 但这是错误的,正如许多开发人员所 ...

  4. Java泛型:类型擦除

    前情回顾 Java泛型:泛型类.泛型接口和泛型方法 类型擦除 代码片段一 1 2 3 4 5 6 7 Class c1 = new ArrayList<Integer>().getClas ...

  5. java中map转为json数据_Java技术-将java中Map类型数据转化为json数据并以Ajax形式返回...

    Java技术-将java中Map类型数据转化为json数据并以Ajax形式返回html 1.自定义工具类(简单易用)-下面是我写的一个简单的工具类前端 package com.test.util; i ...

  6. Java中long类型直接赋值大数字的问题

    原文出处: Java中long类型直接赋值大数字的问题 作者: Jet Mah from Java堂 声明: 可以非商业性任意转载, 转载时请务必以超链接形式标明文章原始出处.作者信息及此声明! 在J ...

  7. Elasticsearch中字段类型(Field Type)详解

    ElasticSearch 7.7 字段类型(Field datatype)详解 字符串, object, 数值, 日期, 数组, 0x00 字符串: text, keyword 5.0以后,stri ...

  8. java char 计算_经典Java面试题之Java中Char类型的运算

    经典Java面试题之Java中Char类型的运算 char在java中称为"字符型",占2个字节.本文是百分网小编搜索整理的关于经典Java面试题之Java中Char类型的运算,有 ...

  9. Java中BigDecimal类型的加减乘除及大小比对

    Java中BigDecimal类型的加减乘除及大小比对 前言 BigDecimal解释 创建BigDecimal类型 加减乘除计算 结果分析 结论 除法的补充 两个BigDecimal的比对 前言 在 ...

最新文章

  1. 数据库 DB database SQL DBMS
  2. shopee本土店怎么做,一些运营技巧分享
  3. devexpress能开发出html,DevExpress推出HTML5 JavaScript控件集
  4. 在zabbix中添加监控主机及Items
  5. HDOJ 2526 HDU 2526 浪漫手机 ACM 2526 IN HDU
  6. Linux|Qt工作笔记-linux系统下安装qt4.5.3版本的详细步骤
  7. SpringBoot面试题第一弹
  8. PyTorch 入坑八:卷积与转置卷积
  9. PHP邮件扩展,PHP邮件扩展:mailpp
  10. zblog仿站教程 - 常用模板标签
  11. sever串口wifi拓展板_什么是串口WIFI模块
  12. python的debug为什么点第一行直接运行结束了_Python 代码调试工具 pdb 快速入门
  13. 四分位距IQR interquartile range
  14. Unity发布VR项目到Android
  15. mysql | left join 出现的结果会重复的问题
  16. 【群晖NAS】真·免费内网穿透方案 及踩坑合集
  17. 执行引擎的工作过程、Java代码编译和执行的过程、解释器、JIT编译器
  18. win7更改锁屏壁纸-强迫症系列
  19. Nginx+Tomcat负载均衡、动静分离
  20. AS608指纹模块的上位机检测

热门文章

  1. 腾讯云安装mysql本地主机名,腾讯云服务器上安装mysql,并用navicat连接
  2. java比较两个对象重写,不重写equals进行两个对象间的深度比较
  3. 查看UNIX/Linux资源占用的top命令
  4. STL 之remove,remove_if,remove_copy,remove_copy_if
  5. 互斥体CMutex的使用
  6. 容器化技术如何在数据中心实践
  7. 如何获取Google地图API密钥?(翻译版)
  8. docker学习笔记(三)docker中的网络
  9. 如果现在还要设计一个新系统,为什么选择 Kafka 而不是 RabbitMQ?
  10. 喜提 redir contributor