超详细的JVM反射原理技术点总结哦~
原创
一、反射概述
Java反射(Reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。
二、反射的核心功能
反射核心提供以下功能:
- 在运行时判断任意一个对象所属的类;
- 在运行时构造任意一个类的对象;
- 在运行时判断任意一个类所具有的成员变量和方法;
- 在运行时调用任意一个对象的方法;
- 生成动态代理。
三、反射的基石:Class类
在Java中,将类的结构信息(成员变量、方法、构造函数等)保存在一个类对象中,这个类对象就是Class对象。当我们编写一个Java类时,编译器会自动为我们生成一个Class对象,这个Class对象保存在同名的.class文件中。
在程序运行时,当需要加载某个类时,Java虚拟机(JVM)会使用类加载器将对应的Class对象加载到内存中。一旦Class对象被加载到内存,我们就可以通过反射来获取这个类的结构信息。
四、反射相关的核心类
- Class类:反射的基石,代表类的实体,在运行时提供涉及类的结构信息。
- Field类:描述类的成员变量,可以用来获取和设置类之中的字段。
- Method类:代表类的方法,可以用来获取类中的方法信息或者执行类和对象的方法。
- Constructor类:代表类的构造方法,可以用来获取类的构造函数信息或者创建类的实例。
五、反射的使用
1. 获取Class对象
有以下三种做法获取Class对象:
- 通过Object类的getClass()方法获取:
// 假设有一个Person类
Person person = new Person();
Class> clazz = person.getClass();
- 通过Class.forName()静态方法获取:
Class> clazz = Class.forName("com.example.Person");
- 通过类名.class获取:
Class> clazz = Person.class;
2. 创建对象
// 通过Class对象创建实例
Object obj = clazz.newInstance();
3. 访问成员变量
// 获取成员变量
Field field = clazz.getDeclaredField("name");
// 设置对私有成员的访问
field.setAccessible(true);
// 获取对象
Object obj = clazz.newInstance();
// 设置成员变量值
field.set(obj, "张三");
// 获取成员变量值
String name = (String) field.get(obj);
4. 调用方法
// 获取方法
Method method = clazz.getDeclaredMethod("setName", String.class);
// 设置对私有方法的访问
method.setAccessible(true);
// 创建对象
Object obj = clazz.newInstance();
// 调用方法
method.invoke(obj, "张三");
六、反射的优缺点
优点:
- 提升程序的灵活性和扩展性;
- 动态创建对象和编译,降低程序的耦合度。
缺点:
- 性能损耗,反射涉及动态解析,于是会消耗更多资源;
- 平安问题,反射破坏了封装性,也许会对系统平安造成影响。