Java反射机制

简介: Java反射机制

什么是反射机制

在运行过程中,对于任何一个类,都能够知道其所有的属性和方法,对于任意一个对象,都能够调用其属性和方法,这种能够动态的获取和调用对象方法的功能,这就是Java的反射机制。

反射的作用

“正向”操作的代码代码在编译之前,就需要明确要运行的类是哪个类

而使用“反向”(反射)创建对象时,只有在代码真正运行的时候,才知道运行的类是哪个

很多场景的情况下,在代码运行之前我们是并不知道要具体使用哪个类的,或者说在运行的时候才来决定到底使用哪个类

// 反射作用

可以设计出更为通用和灵活的架构,很多框架为了保证其通用性,可以根据配置加载不用的类,这时候要用到反射

// 除此之外

动态代理:在不改变目标对象方法的情况下对方法进行增强,比如使用 AOP 拦截某些方法打印日志,这就需要通过反射执行方法中的内容。

注解:利用反射机制,获取注解并执行对应的行为。

反射的优缺点

优点:在运行时动态获取类和对象中的内容,极大地提高系统的灵活性和扩展性;夸张一些说,反射是框架设计的灵魂。

缺点:会有一定的性能损耗,JVM 无法对这些代码进行优化;破坏类的封装性。

应用场景

// 为使用者的服务端添加新的功能

由于为使用着的服务端添加新的功能时,采取在其中new一个含有该新功能的类不够扩展,也难以实现。而反射只要得到(加载)配置文件中的类字符串,再由类的字符串得到该类的字节码文件,然后在得到该类的接口类,最后运行接口类即可运行类中的功能。


反射常用方法

Field :可以使用 get 和 set 方法读取和修改对象的属性;
Method :可以使用 invoke() 方法调用对象中的方法;
Constructor :可以用 newInstance() 创建新的对象。

获取Class类实例化对象的方式

// 获取Class类实例化对象的方式
1、Class.forName(“全类名”)
使用Class类中的 forName() 静态方法,将字节码文件加载进内存,返回Class对象。
多用于配置文件,将类名定义在配置文件中。读取文件,加载类。
推荐使用这种方式。
2、类名.class
通过类名的属性class获取。
多用于参数的传递。
3、对象.getClass()
getClass()方法在Object类中定义着。
多用于对象的获取字节码文件的方式。

获取构造方法

// 获取构造方法
通过Class类中某些方法可以获取对应类中声明的构造方法实例对象
1.Constructor<?>[] getConstructors():返回该Class对象表示类中包含的所有public构造方法(不含继承)所对应的Constructor对象数组。
2.Constructor getConstrutor(Class<?>… parameterTypes):返回与该Class对象表示类中参数列表相匹配的public构造方法(不含继承)对应的Constructor对象。
3.Constructor<?>[] getDeclaredConstructors():返回该Class对象表示类中声明的所有构造方法(不区分访问权限)所对应的Constructor对象数组。
4.Constructor<T> getDeclaredConstructor(Class<?>… parameterTypes):返回与该Class对象表示类中参数列表相匹配的构造方法(不区分访问权限)对应的Constructor对象。

查看构造方法信息

// 查看构造方法信息
通过Constructor类中某些方法可以获取某个构造方法的信息
1.Class<T> getDeclaringClass():返回声明Constructor对象对应构造方法的类的Class对象。
2.int getModifiers():以整数形式返回Constructor对象表示的构造方法的修饰符。
3.String getName() :以字符串形式返回Constructor对象所表示的构造方法的名称。
4.Class<?>[] getParameterTypes():返回由Constructor对象所表示的构造方法的形参类型对应Class对象组成的数组 。如果构造方法没有参数,则数组长度为0。

操作构造方法

// 操作构造方法
通过Constructor类中某些方法可以创建对象
1.void setAccessible(boolean flag):调用构造方法时是否忽略访问权限的影响,true表示忽略,false表示不忽略。
2.T newInstance(Object… initargs):使用此Constructor对象表示的构造方法来创建声明该构造方法类的新对象。initargs为传入该构造方法中的参数,如果该构造方法没有参数,则可设定为null或一个长度为0的数组。

获取成员方法

// 获取成员方法
借助Class类中某些方法可以获取对应类中声明的成员方法实例对象
1.Method[] getMethods():返回该Class对象表示类或接口中所有public方法(含继承的)对应的Method对象数组。
2.Method getMethod(String methodName, Class<?>… parameterTypes):返回与该Class对象表示类或接口中方法名和方法形参类型相匹配的public方法(含继承的)的Method对象。
3.Method[] getDeclaredMethods():返回该Class对象表示类或接口内声明定义的所有访问权限的方法(不含继承的)对应的Method对象数组。
4.Method getDeclaredMethod(String methodName,Class<?>… parameterTypes) :返回与该Class对象表示类或接口中方法名和方法形参类型相匹配方法(不含继承的)对应的Method对象。
// 获取

查看成员方法信息

// 查看成员方法信息
通过Method类中某些方法可以获取某个成员方法的信息
1.Class<?> getDeclaringClass():返回声明Method对象表示方法的类或接口的 Class 对象。
2.int getModifiers():以整数形式返回此Method对象所表示方法的修饰符。应该使用Modifier类中的toString方法对所返回的整数进行解码。
3.Class<?> getReturnType():返回Method对象所表示的方法的返回值类型所对应的Class对象。
4.String getName():返回方法名。
5.Class<?>[] getParameterTypes():返回由Method对象代表方法的形参类型对应Class对象组成的数组。如果方法没有参数,则数组长度为 0。
6.Class<?>[] getExceptionTypes():返回由Method对象表示方法抛出异常类型对应Class对象组成的数组。如果此方法没有在其 throws子句中声明异常,则返回长度为 0 的数组。

操作成员方法

// 操作成员方法
通过Method类中某些方法可以调用成员方法
1.void setAccessible(boolean flag):调用方法时是否忽略访问权限的影响,true表示忽略,false表示不忽略。
2.Object invoke(Object obj, Object… args):调用Method对象指代的方法并返回Object类型结果。obj表示该方法所在类实例,如果方法时静态的则obj可以指定为null; args表示传入该方法的参数,如果方法没有参数,则args数组长度可以为0或null 

获取成员变量

// 获取成员变量
通过Class类中某些方法可以获取对应类中声明的成员变量实例对象
1.Field[] getFields():返回该Class对象表示类或接口中所有public属性(含继承的)对应的Field对象数组。
2.Field getField(String fieldName):返回该Class对象表示类或接口中与指定属性名(含继承的)相同的public 属性对应的Field对象。
3.Field[] getDeclaredFields():返回该Class对象表示类或接口内定义的所有属性(不含继承的)对应的Field对象数组。
4.Field getDeclaredField(String fieldName) :返回与该Class对象表示类或接口内定义的属性名(不含继承的)相匹配的属性相对应的Field对象

查看成员变量信息

// 查看成员变量信息
通过Field类中某些方法可以获取某个成员变量的信息
1.Class<?> getDeclaringClass():返回声明Field对象表示字段的类或接口所对应的Class对象。
2.int getModifiers():以整数形式返回Field对象表示的字段的修饰符。
3.Class<?> getType():返回Field对象所表示字段的数据类型所对应的Class对象(推荐)。
4.Type getGenericType():返回此Field对象所表示字段的声明类型。
5.String getName():返回Field对象表示字段的名称。

操作成员变量

// 操作成员变量
通过Field类中某些方法获取及设置成员变量的值
1.void setAccessible(boolean flag):设置或获取属性值时是否忽略访问权限的影响,true表示忽略,false表示不忽略。
2.Object get(Object obj):返回Field表示字段的Object类型的值。obj为该属性所在类创建的对象,如果该属性是静态的,则可设置为null。
3.void set(Object obj, Object value):为Field对象表示属性设置新值。obj为该属性所在类创建的对象,如果该属性为静态的则设置为null;value为该属性新值。
目录
相关文章
|
5月前
|
设计模式 人工智能 安全
AQS:Java 中悲观锁的底层实现机制
AQS(AbstractQueuedSynchronizer)是Java并发包中实现同步组件的基础工具,支持锁(如ReentrantLock、ReadWriteLock)和线程同步工具类(如CountDownLatch、Semaphore)等。Doug Lea设计AQS旨在抽象基础同步操作,简化同步组件构建。 使用AQS需实现`tryAcquire(int arg)`和`tryRelease(int arg)`方法以获取和释放资源,共享模式还需实现`tryAcquireShared(int arg)`和`tryReleaseShared(int arg)`。
251 32
AQS:Java 中悲观锁的底层实现机制
|
3月前
|
人工智能 缓存 安全
Java中的反射机制:深入探索与应用
Java反射机制是程序运行时动态获取类信息并操作类成员的特性,具备高度灵活性,但也伴随性能与安全风险。本文详解反射的基本用法、高级应用及最佳实践,助你掌握这一强大工具的正确使用方式。
136 0
|
5月前
|
人工智能 Java 关系型数据库
Java——SPI机制详解
SPI(Service Provider Interface)是JDK内置的服务提供发现机制,主要用于框架扩展和组件替换。通过在`META-INF/services/`目录下定义接口实现类文件,Java程序可利用`ServiceLoader`动态加载服务实现。SPI核心思想是解耦,允许不同厂商为同一接口提供多种实现,如`java.sql.Driver`的MySQL与PostgreSQL实现。然而,SPI存在缺陷:需遍历所有实现并实例化,可能造成资源浪费;获取实现类方式不够灵活;多线程使用时存在安全问题。尽管如此,SPI仍是Java生态系统中实现插件化和模块化设计的重要工具。
159 0
|
3月前
|
人工智能 前端开发 安全
Java开发不可不知的秘密:类加载器实现机制
类加载器是Java中负责动态加载类到JVM的组件,理解其工作原理对开发复杂应用至关重要。本文详解类加载过程、双亲委派模型及常见类加载器,并介绍自定义类加载器的实现与应用场景。
186 4
|
3月前
|
人工智能 安全 Java
掌握Java反射:在项目中高效应用反射机制
Java反射是一种强大功能,允许程序在运行时动态获取类信息、创建对象、调用方法和访问字段,提升程序灵活性。它在框架开发、动态代理、注解处理等场景中广泛应用,如Spring和Hibernate。但反射也存在性能开销、安全风险和代码复杂性,应谨慎使用。
|
4月前
|
人工智能 Java
Java中的反射机制:深入探索与应用
本文介绍了Java反射机制的基本概念、用途及其实现方式。反射机制允许程序在运行时动态获取类的属性和方法,并调用它们,适用于处理私有成员或权限受限的情况。文章详细讲解了`Class`类的功能,包括获取类的方法、属性、注解、构造器等信息,以及通过四种方式获取`Class`对象的示例代码。此外,还探讨了类加载器、继承关系判断、动态代理等高级内容,展示了如何在运行时创建接口实例并处理方法调用。文末提供了完整的代码示例以加深理解。
Java中的反射机制:深入探索与应用
|
5月前
|
Java 区块链 网络架构
酷阿鲸森林农场:Java 区块链系统中的 P2P 区块同步与节点自动加入机制
本文介绍了基于 Java 的去中心化区块链电商系统设计与实现,重点探讨了 P2P 网络在酷阿鲸森林农场项目中的应用。通过节点自动发现、区块广播同步及链校验功能,系统实现了无需中心服务器的点对点网络架构。文章详细解析了核心代码逻辑,包括 P2P 服务端监听、客户端广播新区块及节点列表自动获取等环节,并提出了消息签名验证、WebSocket 替代 Socket 等优化方向。该系统不仅适用于农业电商,还可扩展至教育、物流等领域,构建可信数据链条。
|
5月前
|
人工智能 JavaScript Java
Java反射机制及原理
本文介绍了Java反射机制的基本概念、使用方法及其原理。反射在实际项目中比代理更常用,掌握它可以提升编程能力并理解框架设计原理。文章详细讲解了获取Class对象的四种方式:对象.getClass()、类.class、Class.forName()和类加载器.loadClass(),并分析了Class.forName()与ClassLoader的区别。此外,还探讨了通过Class对象进行实例化、获取方法和字段等操作的具体实现。最后从JVM类加载机制角度解析了Class对象的本质及其与类和实例的关系,帮助读者深入理解Java反射的工作原理。
104 0
|
7月前
|
缓存 Dubbo Java
理解的Java中SPI机制
本文深入解析了JDK提供的Java SPI(Service Provider Interface)机制,这是一种基于接口编程、策略模式与配置文件组合实现的动态加载机制,核心在于解耦。文章通过具体示例介绍了SPI的使用方法,包括定义接口、创建配置文件及加载实现类的过程,并分析了其原理与优缺点。SPI适用于框架扩展或替换场景,如JDBC驱动加载、SLF4J日志实现等,但存在加载效率低和线程安全问题。
278 7
理解的Java中SPI机制
|
6月前
|
存储 Java 编译器
Java 中 .length 的使用方法:深入理解 Java 数据结构中的长度获取机制
本文深入解析了 Java 中 `.length` 的使用方法及其在不同数据结构中的应用。对于数组,通过 `.length` 属性获取元素数量;字符串则使用 `.length()` 方法计算字符数;集合类如 `ArrayList` 采用 `.size()` 方法统计元素个数。此外,基本数据类型和包装类不支持长度属性。掌握这些区别,有助于开发者避免常见错误,提升代码质量。
474 1