通过反射了解泛型的本质

2024-09-04 21:32
文章标签 了解 反射 泛型 本质

本文主要是介绍通过反射了解泛型的本质,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

通过Class,Method来认识泛型的本质
我们知道Java中集合的泛型是防止错误输入的,例如ArrayList<String>list1=new ArrayList<String>();接下来如果再有list1.add(20);系统便提示错误,程序无法通过编译,以为list1的类型已被指定为String,那么我们看以下代码

Class c1=list.getClass();
Class c2=list1.getClass();
System.out.println(c1==c2);

此时系统输出的是却是true,未使用泛型的list和使用泛型指定唯一类型Stringlist1具有相同的类类型(getClass()方法返回类的类类型)吗??
原因在于——泛型只在编译阶段有效,编译完成后自动去泛型化,而反射操作都是编译之后的操作,下面我们举例加深理解。

package 反射与泛型;
import java.lang.reflect.Method;
import java.util.*;
public class Example {public static void main(String[] args) {ArrayList list=new ArrayList();ArrayList<String>list1=new ArrayList<String>();list1.add("hello");//list1.add(20);错误的,编译不通过Class c1=list.getClass();Class c2=list1.getClass();System.out.println(c1==c2);//反射的操作都是编译之后的操作///** c1==c2结果返回true说明编译之后集合的泛型是去泛型化的* Java中集合的泛型是防止错误输入的,只在编译阶段有效,绕过编译就无效了* 验证:我们可以通过方法的反射来操作,绕过编译* */try {Method m=c2.getMethod("add", Object.class);m.invoke(list1, 20);//绕过编译操作就绕过了泛型System.out.println(list1.size());} catch (Exception e) {e.printStackTrace();} }
}

这里写图片描述

很显然,我们成功地使用反射绕过了泛型为list1添加了一个int类型的元素20,说明绕过绕过编译操作也就绕过了泛型。

总结

此刻,我们对于泛型和反射有了一定的认识,但是编译过程到底是如何实现的,底层类的加载执行又有哪些细节,还有待于深入学习。

这篇关于通过反射了解泛型的本质的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1137085

相关文章

Java反射实现多属性去重与分组功能

《Java反射实现多属性去重与分组功能》在Java开发中,​​List是一种非常常用的数据结构,通常我们会遇到这样的问题:如何处理​​List​​​中的相同字段?无论是去重还是分组,合理的操作可以提高... 目录一、开发环境与基础组件准备1.环境配置:2. 代码结构说明:二、基础反射工具:BeanUtils

Java使用MethodHandle来替代反射,提高性能问题

《Java使用MethodHandle来替代反射,提高性能问题》:本文主要介绍Java使用MethodHandle来替代反射,提高性能问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录一、认识MethodHandle1、简介2、使用方式3、与反射的区别二、示例1、基本使用2、(重要)

C#特性(Attributes)和反射(Reflection)详解

《C#特性(Attributes)和反射(Reflection)详解》:本文主要介绍C#特性(Attributes)和反射(Reflection),具有很好的参考价值,希望对大家有所帮助,如有错误... 目录特性特性的定义概念目的反射定义概念目的反射的主要功能包括使用反射的基本步骤特性和反射的关系总结特性

一文详解Java异常处理你都了解哪些知识

《一文详解Java异常处理你都了解哪些知识》:本文主要介绍Java异常处理的相关资料,包括异常的分类、捕获和处理异常的语法、常见的异常类型以及自定义异常的实现,文中通过代码介绍的非常详细,需要的朋... 目录前言一、什么是异常二、异常的分类2.1 受检异常2.2 非受检异常三、异常处理的语法3.1 try-

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类

C# Where 泛型约束的实现

《C#Where泛型约束的实现》本文主要介绍了C#Where泛型约束的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录使用的对象约束分类where T : structwhere T : classwhere T : ne

java中反射(Reflection)机制举例详解

《java中反射(Reflection)机制举例详解》Java中的反射机制是指Java程序在运行期间可以获取到一个对象的全部信息,:本文主要介绍java中反射(Reflection)机制的相关资料... 目录一、什么是反射?二、反射的用途三、获取Class对象四、Class类型的对象使用场景1五、Class

一文带你了解SpringBoot中启动参数的各种用法

《一文带你了解SpringBoot中启动参数的各种用法》在使用SpringBoot开发应用时,我们通常需要根据不同的环境或特定需求调整启动参数,那么,SpringBoot提供了哪些方式来配置这些启动参... 目录一、启动参数的常见传递方式二、通过命令行参数传递启动参数三、使用 application.pro

一文带你深入了解Python中的GeneratorExit异常处理

《一文带你深入了解Python中的GeneratorExit异常处理》GeneratorExit是Python内置的异常,当生成器或协程被强制关闭时,Python解释器会向其发送这个异常,下面我们来看... 目录GeneratorExit:协程世界的死亡通知书什么是GeneratorExit实际中的问题案例

Spring 中使用反射创建 Bean 实例的几种方式

《Spring中使用反射创建Bean实例的几种方式》文章介绍了在Spring框架中如何使用反射来创建Bean实例,包括使用Class.newInstance()、Constructor.newI... 目录1. 使用 Class.newInstance() (仅限无参构造函数):2. 使用 Construc