java中的类型擦除type erasure
文章目录
- 简介
- 举个例子
- 原因
- 解决办法
- 总结
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相关推荐
- java 类型擦除_java中的类型擦除type erasure
简介 泛型是java从JDK 5开始引入的新特性,泛型的引入可以让我们在代码编译的时候就强制检查传入的类型,从而提升了程序的健壮度. 泛型可以用在类和接口上,在集合类中非常常见.本文将会讲解泛型导致的 ...
- 泛型中的类型擦除和桥方法
在Java中,泛型的引入是为了在编译时提供强类型检查和支持泛型编程.为了实现泛型,Java编译器应用类型擦除实现: 1. 用类型参数(type parameters)的限定(如果没有就用Object ...
- java 泛型和类型擦除_关于Java泛型和擦除
java 泛型和类型擦除 "编译期间擦除泛型"是常识(好吧,类型参数和实参实际上是被擦除的). 这是由于"类型擦除"而发生的. 但这是错误的,正如许多开发人员所 ...
- Java泛型:类型擦除
前情回顾 Java泛型:泛型类.泛型接口和泛型方法 类型擦除 代码片段一 1 2 3 4 5 6 7 Class c1 = new ArrayList<Integer>().getClas ...
- java中map转为json数据_Java技术-将java中Map类型数据转化为json数据并以Ajax形式返回...
Java技术-将java中Map类型数据转化为json数据并以Ajax形式返回html 1.自定义工具类(简单易用)-下面是我写的一个简单的工具类前端 package com.test.util; i ...
- Java中long类型直接赋值大数字的问题
原文出处: Java中long类型直接赋值大数字的问题 作者: Jet Mah from Java堂 声明: 可以非商业性任意转载, 转载时请务必以超链接形式标明文章原始出处.作者信息及此声明! 在J ...
- Elasticsearch中字段类型(Field Type)详解
ElasticSearch 7.7 字段类型(Field datatype)详解 字符串, object, 数值, 日期, 数组, 0x00 字符串: text, keyword 5.0以后,stri ...
- java char 计算_经典Java面试题之Java中Char类型的运算
经典Java面试题之Java中Char类型的运算 char在java中称为"字符型",占2个字节.本文是百分网小编搜索整理的关于经典Java面试题之Java中Char类型的运算,有 ...
- Java中BigDecimal类型的加减乘除及大小比对
Java中BigDecimal类型的加减乘除及大小比对 前言 BigDecimal解释 创建BigDecimal类型 加减乘除计算 结果分析 结论 除法的补充 两个BigDecimal的比对 前言 在 ...
最新文章
- 数据库 DB database SQL DBMS
- shopee本土店怎么做,一些运营技巧分享
- devexpress能开发出html,DevExpress推出HTML5 JavaScript控件集
- 在zabbix中添加监控主机及Items
- HDOJ 2526 HDU 2526 浪漫手机 ACM 2526 IN HDU
- Linux|Qt工作笔记-linux系统下安装qt4.5.3版本的详细步骤
- SpringBoot面试题第一弹
- PyTorch 入坑八:卷积与转置卷积
- PHP邮件扩展,PHP邮件扩展:mailpp
- zblog仿站教程 - 常用模板标签
- sever串口wifi拓展板_什么是串口WIFI模块
- python的debug为什么点第一行直接运行结束了_Python 代码调试工具 pdb 快速入门
- 四分位距IQR interquartile range
- Unity发布VR项目到Android
- mysql | left join 出现的结果会重复的问题
- 【群晖NAS】真·免费内网穿透方案 及踩坑合集
- 执行引擎的工作过程、Java代码编译和执行的过程、解释器、JIT编译器
- win7更改锁屏壁纸-强迫症系列
- Nginx+Tomcat负载均衡、动静分离
- AS608指纹模块的上位机检测
热门文章
- 腾讯云安装mysql本地主机名,腾讯云服务器上安装mysql,并用navicat连接
- java比较两个对象重写,不重写equals进行两个对象间的深度比较
- 查看UNIX/Linux资源占用的top命令
- STL 之remove,remove_if,remove_copy,remove_copy_if
- 互斥体CMutex的使用
- 容器化技术如何在数据中心实践
- 如何获取Google地图API密钥?(翻译版)
- docker学习笔记(三)docker中的网络
- 如果现在还要设计一个新系统,为什么选择 Kafka 而不是 RabbitMQ?
- 喜提 redir contributor