Java泛型类型擦除以及类型擦除带来的问题--什么是泛型擦除

简介: Java泛型是伪泛型,编译后类型信息被擦除,仅保留原始类型。如`ArrayList<String>`与`ArrayList<Integer>`在运行时均为`ArrayList`,通过反射可绕过泛型限制添加非指定类型元素,证明泛型仅在编译期生效,JVM无法感知其存在。

我们都知道Java的泛型是伪泛型,即编译期间所有的泛型信息都会被擦除,如我们代码定义了:List和List,但是对于JVM而言,看到的只有List,由泛型附加的类型信息对于JVM而言是看不到的。代码说明如下:

1.1 原始类型擦除后相等
public class Test {
public static void main(String[] args) {
ArrayList list1 = new ArrayList();
list1.add("abc");

    ArrayList<Integer> list2 = new ArrayList<Integer>();
    list2.add(123);

    System.out.println(list1.getClass() == list2.getClass());
}

}
在这个例子中,我们定义了两个ArrayList数组,不过一个是ArrayList泛型类型的,只能存储字符串;一个是ArrayList泛型类型的,只能存储整数,最后,我们通过list1对象和list2对象的getClass()方法获取他们的类的信息,最后发现结果为true。说明泛型类型String和Integer都被擦除掉了,只剩下原始类型。

1.2 反射添加的元素被擦除
public static void main(String[] args)
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
ArrayList list = new ArrayList();
list.add(1); //这样调用 add 方法只能存储整形,因为泛型类型的实例为 Integer
list.getClass().getMethod("add", Object.class).invoke(list, "asd");

    for (int i = 0; i < list.size(); i++) {
        // 输出1    asd
        System.out.println(list.get(i));
    }
}

如果直接调用add()方法,那么只能存储整数数据,不过当我们利用反射调用add()方法的时候,却可以存储字符串,这说明了Integer泛型实例在编译之后被擦除掉了,只保留了原始类型。

相关文章
|
4月前
|
数据采集 人工智能 监控
办公Agent + 企业知识库:自动生成季度报告与竞品分析文档
本文揭秘一款专为企业打造的办公Agent:它能自动连通CRM、飞书、竞品官网等知识源,按模板生成季度复盘与竞品分析初稿,引用皆可溯源。实测报告撰写从12小时缩至3分钟,人工仅需微调。不吹“全能”,只解决找资料慢、信息散、更新滞三大痛点。(239字)
388 4
|
9月前
|
Java
@Inherited 注解
@Inherited使@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan注解可被继承,SpringBoot主启动类因此具备自动配置、组件扫描等功能,简化配置。详情见:@Inherited作用说明。
|
人工智能 移动开发 JavaScript
AI + 低代码技术揭秘(二):核心架构
VTJ低代码平台架构包含引擎编排层、Provider服务系统、数据模型及代码生成管道,支持设计时与运行时功能。Engine管理设计流程,Provider处理服务加载,Simulator实现组件渲染,数据模型通过事件驱动同步状态。代码生成管道可双向转换Vue组件与DSL,支持多平台适配,如Web、H5和UniApp。系统提供可视化编辑、热重载与AI集成,满足高效开发需求。
423 0
|
机器学习/深度学习
【从零开始学习深度学习】23. CNN中的多通道输入及多通道输出计算方式及1X1卷积层介绍
【从零开始学习深度学习】23. CNN中的多通道输入及多通道输出计算方式及1X1卷积层介绍
【从零开始学习深度学习】23. CNN中的多通道输入及多通道输出计算方式及1X1卷积层介绍
@Documented注解
该注解可用于生成Javadoc文档,结合@Target、@Retention等元注解,是实现自定义注解的基础。掌握其用法可提升代码可读性与开发效率。详情可参考“自定义注解”教程。
|
9月前
|
Java 测试技术 Apache
安装Jmeter
JMeter依赖JDK,需先安装并配置JDK环境变量。前往Apache JMeter官网(http://jmeter.apache.org/download_jmeter.cgi)下载最新版本,解压后即可使用,适用于性能测试与负载模拟。
|
9月前
|
安全 Java 开发工具
整合SpringSecurity
本文介绍了Spring Security与Spring Boot的整合步骤:引入依赖、启动验证及登录测试。通过日志变化和自动跳转至login页面验证集成成功,使用默认用户名user和控制台生成的动态密码登录后,可访问受保护资源。完整代码见GitHub仓库Day01分支。
@Target注解
@Target注解用于指定自定义注解的作用目标,如类、接口、字段、方法、参数、构造函数、局部变量、注解类型及包,确保注解只能在指定程序元素上使用,提升代码规范性与可读性。
|
9月前
|
Java 容器 Spring
SpringBoot怎么过滤不需要的组件
Spring Boot中IOC容器确实存在,若不想某些Bean在启动时注入,可通过@ComponentScan指定扫描范围,或自定义TypeExcludeFilter排除特定类,也可在配置文件中设置过滤规则,灵活控制Bean加载。
|
9月前
|
Java
@SpringBootConfiguration注解
@SpringBootConfiguration是@Configuration的封装,标注主启动类,使其所在包成为组件扫描的根路径。因此主类需置于外层包,确保所有组件被扫描到,实现自动配置与组件注入。

热门文章

最新文章