Java-反射机制总结
一、反射机制
1.1 概念
反射机制是指在运行时动态地获取和操作类的信息、对象的属性和方法的能力。通过反射,可以在编译时无法确定的情况下,通过获取类的元数据信息,实现对类、对象、方法的检查、调用和操作。
-
理解:
-
反射机制允许:程序在执行期间借助于Reflection API取得任何类的内部信息(比如成员变量,构造方法,成员方法等的),并且能够操作对象的属性及方法。【在 设计模式 和 框架的底层 常用】
-
类加载完后,在堆中产生一个Class类型的对象(一个类仅产生一个Class对象),这个Class类型的对象包含了类的完整结构信息。
-
通过这个Class类型的对象,可以得到类的结构以及各种类的信息,因此,Class对象就像一面镜子,透过镜子可以看到类的结构,所以形象地成为反射。
-
1.2 反射机制原理图
-
回顾Java程序运行过程:
- 1.编码:编写源代码(.java文件)
- 2.编译:通过编译器(javac)编译成字节码(.class文件)
- 3.类加载器加载:Java虚拟机(JVM)的类加载器将字节码文件(.class)加载到内存中;
- 4.字节码验证:如结构,语义,类型等验证;
- 5.执行:Java虚拟机解释字节码指令进行执行;
-
以"反射机制引入"中的需求为例,绘制反射机制原理图如下:

二、反射机制相关的类
- 主要的类如下:
| 类名 | 所在包名 | 描述 |
|---|---|---|
| Class | java.lang.Class | 代表一个类,Class对象表示某个类加载后在堆中的对象 |
| Method | java.lang.reflection.Method | 代表类的方法 |
| Field | java.lang.reflect.Field | 代表类的成员变量 |
| Constructor | java.lang.reflect.Constructor | 代表类的构造方法 |
2.1 相关类的用法
-
通过反射获取类的成员变量:
- 自定义的Cat类
/** * @author: sea * @date: 2023/5/23 16:33 */ public class Cat { private String name; public int age = 10; public void hi(){ System.out.println("hihihi"); } public void cry(){ System.out.println("miamiamia"); } }- 用法:
/** * @author: sea * @date: 2023/5/29 09:22 */ public class Reflection_02_Field_Constructor { public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { String filePath = "./hsp_ch23/re.properties"; Properties properties = new Properties(); properties.load(new FileReader(filePath)); String classFullPath = properties.getProperty("classfullpath"); String method = properties.getProperty("method"); //可以从文件中读取到 类的路径 和 方法名称,但是如果不使用反射机制的话,无法通过路径创建类的对象 System.out.println("classfullpath=" + classFullPath + "\n" + "method=" + method); //(1) 通过 类的路径 加载 类,返回的是Class类型的对象aClass Class aClass = Class.forName(classFullPath); //(2) 通过 aClass 得到 加载的类(hsp_ch23.Reflection_.Cat)的对象实例 Object o = aClass.newInstance(); System.out.println("对象实例 o 的运行类型:" + aClass.newInstance().getClass()); //(3) 通过 aClass 可以获取到 加载的类(hsp_ch23.Reflection_.Cat)中名称为 读取到的method值 的方法对象(Method类的对象) // 即:在反射中,方法也视为一个对象 Method method1 = aClass.getMethod(method); //(4) 通过 method1 来实现方法的调用 method1.invoke(o);//此处,有点绕,传统方式:通过 对象示例 调用 类的方法【o.method1()】。 此处:方法.invoke(对象); //获取类的成员变量(Field对象) Field name = aClass.getField("name"); System.out.println(name.get(o));// ==> o.name Field age = aClass.getField("age"); System.out.println(age.get(o)); //获取构造器 // (1)无参构造器 Constructor constructor1 = aClass.getConstructor(); System.out.println(constructor1); // (2)带参构造器 Constructor constructor2 = aClass.getConstructor(String.class); System.out.println(constructor2); } }- 获取成员变量name时会报错,原因:name字段为私有成员变量,不能获取类的私有变量;、
- 通过
setAccessible()方法,传入true,使得可以通过反射来操作私有变量;
- 通过
-
反射机制相对于传统方式效率比较低,原因:反射机制涉及到一些权限检查等步骤。
2.2 哪些类型有Class对象
- 如下类型有Class对象:
- 外部类
- 内部类(局部内部类、匿名内部类、成员内部类、静态内部类)
- 接口:Interface
- 数组:[]、[][]
- 枚举类型:Enum
- 注解:Annotation
- 基本数据类型
- void
本文介绍了Java反射机制的概念,包括其在运行时动态获取和操作类信息的能力。详细讲解了反射原理、相关类的使用(如Class、Method、Field和Constructor),并探讨了如何处理私有变量和反射效率的问题。

被折叠的 条评论
为什么被折叠?



