JAVA-反射
本文最后更新于:2022年9月26日 下午
Java-反射
1.反射的概述:
反射(Reflection),Java反射机制是在运行状态时,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java的反射机制。
反射是java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API获取任何类的内部信息,并且能直接操作任意对象的内部属性及方法。
1 |
|
流程示意图:
举例理解反射:
假设一个人意外死亡,法医需要解剖来查看他的死因,以及他的属性(年龄,体重,呼吸道,各类器官…)
因为人已经死亡,我们解剖的过程也可以形象的理解为“反射”。得到完整的“包类名称”就相当于解剖获得器官的过程。
反射相关的主要API:
- java.lang.Class: 代表一个类
- java.lang.reflect.Method: 代表类的方法
- java.lang.reflect.Field: 代表类的成员变量
- java.lang.reflect.Constructor: 代表类的构造器
Class类的常用方法:
方法名 | 功能 |
---|---|
static ClassforName(String name) | 返回指定类名name的Class对象 |
newInstance() | 在内存中生成一个实例 |
getName() | 返回当前Class对象所表示的实体(类,接口,数组类或void)的名称 |
Class getSuperClass() | 返回当前Class对象的父类的Class对象 |
Class[] getinterfaces() | 获取当前Class对象的接口 |
ClassLoader getClassLoader() | 返回该类的类加载器 |
Field[] getDeclaredFields | 返回Field对象的一个数组 |
Method getMethed(String name,Class.. parameterTypes) | 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。 |
2.获取Class对象的三种方式
1: 通过该实例变量提供的getClass()
方法获取:
2: 通过静态方法Class.forName()
获取(要先知道class的完整类名):
3: 直接通过一个class
的静态变量class获取:
如图:
注意:
运行期间,一个类中只有一个class对象产生,图中c1,c2,c3的hashCode都是相同的。
且平常最常用的方法就是第二种。
获取运行时类的完整结构
1:获取字段
1 |
|
运行结果:
所有通过Class实例的方法可以获取Field实例,getField(),getFields(),getDeclaredField(),getDeclaredFields();
此外Field实例可以读取或设置某个对象的字段,如果存在访问限制,要首先调用setAccessible(true)来访问非public字段。
2:调用方法
1 |
|
运行结果:
通过Class实例的方法可以获取Method实例:getMethod(),getMethods(),getDeclaredMethod(),getDeclaredMethods();
调用指定方法:
通过getMethod(String name,Class…parameterTypes
)方法取得一个Method对象,并设置此方法操作时所需要的类型。之后使用Object invoke(Object obj,Object[] args)
进行调用,并向方法中传递要设置的obj对象的参数信息。若原方法声明为private,则需要在调用此invoke()方法前,显示调用方法对象的setAccessible(true)方法,则可以访问private方法。
注意:Method、Field、Constructor对象都有**setAccessible()**方法。
setAccessible()作用是启用和禁用访问安全检查的开关。
3:获得构造器方法
通过反射来创建新的实例,我们可以调用Class提供的newInstance()
方法:
1 |
|
但是它只能调用该类的public无参数构造方法。如果想要调用任意构造方法,就需要用到API提供的Constructor对象,Constructor对象和Method很类似,但是不同之处仅在于它是一个构造方法,调用结果总是返回实例。
1 |
|
运行结果:
通过Class实例方法可以获取Constructor实例:
getConstructor(),getConstructors(),getDeclaredConstructor(),getDeclaredConstructors()
Java反射的优缺点
优点:
可以实现动态创建对象和编译,有很大的灵活性。
缺点:
对性能有影响,使用反射机制基本上是一种解释操作,我们可以告诉JVM我们希望做什么并且它满足我们的要求,这类操作总是慢于直接执行相同的操作。
测试效果: