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为该属性新值。
目录
相关文章
|
1天前
|
Java 数据库连接 开发者
Java的Shutdown Hook机制:优雅地关闭应用程序
Java的Shutdown Hook机制:优雅地关闭应用程序
20 1
|
1天前
|
Java 程序员 开发者
深入理解Java并发编程:线程同步与锁机制
【4月更文挑战第30天】 在多线程的世界中,确保数据的一致性和线程间的有效通信是至关重要的。本文将深入探讨Java并发编程中的核心概念——线程同步与锁机制。我们将从基本的synchronized关键字开始,逐步过渡到更复杂的ReentrantLock类,并探讨它们如何帮助我们在多线程环境中保持数据完整性和避免常见的并发问题。文章还将通过示例代码,展示这些同步工具在实际开发中的应用,帮助读者构建对Java并发编程深层次的理解。
|
1天前
|
Java
【专栏】Java反射机制,该机制允许程序在运行时获取类信息、动态创建对象、调用方法和访问属性
【4月更文挑战第27天】本文探讨了Java反射机制,该机制允许程序在运行时获取类信息、动态创建对象、调用方法和访问属性。反射通过Class、Constructor、Method和Field类实现。文中列举了反射的应用场景,如动态创建对象、调用方法、访问属性和处理注解,并提供了相关实例代码演示。
|
1天前
|
消息中间件 安全 前端开发
字节面试:说说Java中的锁机制?
Java 中的锁(Locking)机制主要是为了解决多线程环境下,对共享资源并发访问时的同步和互斥控制,以确保共享资源的安全访问。 锁的作用主要体现在以下几个方面: 1. **互斥访问**:确保在任何时刻,只有一个线程能够访问特定的资源或执行特定的代码段。这防止了多个线程同时修改同一资源导致的数据不一致问题。 2. **内存可见性**:通过锁的获取和释放,可以确保在锁保护的代码块中对共享变量的修改对其他线程可见。这是因为 Java 内存模型(JMM)规定,对锁的释放会把修改过的共享变量从线程的工作内存刷新到主内存中,而获取锁时会从主内存中读取最新的共享变量值。 3. **保证原子性**:锁
16 1
|
1天前
|
安全 Java 数据安全/隐私保护
Java一分钟之-Java反射机制:动态操作类与对象
【5月更文挑战第12天】本文介绍了Java反射机制的基本用法,包括获取Class对象、创建对象、访问字段和调用方法。同时,讨论了常见的问题和易错点,如忽略访问权限检查、未捕获异常以及性能损耗,并提供了相应的避免策略。理解反射的工作原理和合理使用有助于提升代码灵活性,但需注意其带来的安全风险和性能影响。
23 4
|
1天前
|
Java 数据安全/隐私保护
java中异常处理机制
java中异常处理机制
13 1
|
1天前
|
算法 安全 Java
深入探索Java中的并发编程:CAS机制的原理与应用
总之,CAS机制是一种用于并发编程的原子操作,它通过比较内存中的值和预期值来实现多线程下的数据同步和互斥,从而提供了高效的并发控制。它在Java中被广泛应用于实现线程安全的数据结构和算法。
23 0
|
1天前
|
Java API 开发者
解密Java反射机制与动态代理
解密Java反射机制与动态代理
14 0
|
1天前
|
Java 数据库连接 开发者
Java中的异常处理机制详解
Java异常处理是确保程序健壮的关键,涉及Throwable的Error和Exception子类。Error由JVM抛出,不建议捕获;Exception分为检查异常(需要捕获)和未检查异常。处理异常的关键字有try、catch、finally、throw和throws。最佳实践包括捕获具体异常、不吞没异常、释放资源和避免滥用异常。示例展示了如何在main方法中处理IOException,并在finally块中进行资源清理。
13 1
|
1天前
|
缓存 NoSQL Java
17:缓存机制-Java Spring
17:缓存机制-Java Spring
41 5