avatar

JAVA反射机制

JAVA反射机制

介绍

java反射机制是在运行状态中,对于任意一个类,都能够得到这个类的所有属性和方法;对于任意一个对象,都能调用它的任意方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为反射机制

获取Class对象的两种方式

1
2
3
4
5
6
7
8
9
// 1.如果我们知道具体的类,可以使用下面的代码,[类名.class];但是通常情况下我们是不知道具体的类的,并且还需要导入类的包,依赖太强。
Class targetClass = TargetObject.class;

// 2.通过[Class.forName()]小括号中传入类的字符串路径获取,字符串可以写在配置文件中。
Class targetClass = Class.forName("frosro.test.TargetObject");

// 3.其实还有一种方法,继承自Object类的getClass方法,如下,但这样对象都已经存在了,我们再用反射就多此一举了。
TargetObject targetObject = new TargetObject();
Class targetClass = targetObject.getClass();

代码演示

首先创建一个我们将要操作的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package fanshe;

/**
* @author sy
* @data 21:35
*/
public class TargetObject {

private String value;

public TargetObject() {
value = "initVal";
}

public void publicMethod(String s) {
System.out.println("I love " + s);
}

private void privateMethod() {
System.out.println("value is " + value);
}
}

然后使用反射来操作这个类的方法和参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package fanshe;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
* @author sy
* @data \ 21:36
*/
public class Main {

public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {

// 获取TargetObject类的Class对象
Class<?> tagetClass = Class.forName("fanshe.TargetObject");
// 创建一个TargetObject类的实例
TargetObject targetObject = (TargetObject)tagetClass .newInstance();


// 获取类中所有定义的方法
Method[] methods = tagetClass.getDeclaredMethods();
for (Method method : methods) {
// 循环输出方法名称
System.out.println(method.getName());
}

// 获取指定方法并调用
Method publicMethod = tagetClass.getDeclaredMethod("publicMethod", String.class);
publicMethod.invoke(targetObject,"frosro");

// 获取指定参数
Field field = tagetClass.getDeclaredField("value");
// 取消安全检查,这样我们就可以访问到私有的属性和方法
field.setAccessible(true);
// 对参数进行修改
field.set(targetObject,"frosro");

// 调用私有的方法
Method privateMethod = tagetClass.getDeclaredMethod("privateMethod");
privateMethod.setAccessible(true);
privateMethod.invoke(targetObject);

}
}

还有其他很多方法,可以翻看文档查找;

反射机制优缺点

  • 优点: 运行期类型的判断,动态加载类,提高代码灵活度。

  • 缺点:

    1.性能瓶颈:反射相当于一系列解释操作,通知 JVM 要做的事情,性能比直接的 java 代码要慢很多。

    2.安全问题:让我们可以动态操作改变类的属性同时也增加了类的安全隐患。

反射的应用场景

在我们平时的项目开发过程中,基本上很少会直接使用到反射机制,但这不能说明反射机制没有用,实际上有很多设计、开发都与反射机制有关,例如模块化的开发,通过反射去调用对应的字节码;动态代理设计模式也采用了反射机制,还有我们日常使用的 Spring/Hibernate 等框架也大量使用到了反射机制。

举例:

  1. 我们在使用 JDBC 连接数据库时使用 Class.forName()通过反射加载数据库的驱动程序;
  2. Spring 框架的 IOC(动态加载管理 Bean)创建对象以及 AOP(动态代理)功能都和反射有联系;
  3. 动态配置实例的属性;
文章作者: Frosro
文章链接: https://frosro.github.io/2020/04/13/JAVA%E5%8F%8D%E5%B0%84%E6%9C%BA%E5%88%B6/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 BETTER LATE THAN NEVER
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论