📌 专栏 :大白话说Java面试题 --- 01-Java基础篇
第39题:说说反射的用途及实现原理,Java获取反射(Class)的三种方法
📚 回答:
- 什么是反射?
Java 的反射机制允许程序在运行时动态获取类的信息(如构造方法、成员变量、方法等),并动态调用对象的功能。这种能力使得程序更加灵活,能够处理未知类型的对象。
1. 反射的实现原理
-
编译阶段:
- Java 程序在编译后会生成
.class文件,这些文件包含了类的元信息(如类名、字段、方法等)。
- Java 程序在编译后会生成
-
运行阶段:
- 当程序运行时,JVM 会将
.class文件加载到内存中,并为每个类生成一个Class对象。 - 通过
Class对象,可以获取类的构造方法(Constructor)、成员变量(Field)、方法(Method)等信息,并动态操作这些内容。
- 当程序运行时,JVM 会将
2. 获取 Class 对象的三种方法
-
方法1:通过类名获取
javaClass<?> clazz = String.class; -
方法2:通过类路径获取
javaClass<?> clazz = Class.forName("java.lang.String"); -
方法3:通过实例化对象获取
javaString str = "Hello"; Class<?> clazz = str.getClass();💡 代码示例 :
以下代码展示了如何通过反射创建对象并调用方法:
java
import java.lang.reflect.Method;
class Person {
private String name;
public Person() {}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class Main {
public static void main(String[] args) throws Exception {
// 获取 Class 对象
Class<?> clazz = Class.forName("Person");
// 创建实例
Object obj = clazz.getDeclaredConstructor().newInstance();
// 获取方法并调用
Method setName = clazz.getMethod("setName", String.class);
setName.invoke(obj, "Alice");
Method getName = clazz.getMethod("getName");
System.out.println(getName.invoke(obj)); // 输出 Alice
}
}
3. 反射的应用场景
-
框架开发:
- Spring 的 IoC 容器通过反射动态创建对象并实现依赖注入。
- Spring MVC 通过反射调用控制器中的方法。
-
动态代理:
- JDK 动态代理底层依赖反射机制。
-
JDBC 驱动加载:
- 使用
Class.forName()加载数据库驱动(如 MySQL 驱动)。
- 使用
-
注解解析:
- 如 JUnit、Spring 等框架通过反射解析注解并执行相应逻辑。
💡 面试官视角:
-
面试官可能会问"反射的优缺点是什么?"答:
- 优点:灵活性高,能够动态操作类和对象。
- 缺点:性能较低,破坏封装性,可能导致安全隐患。
-
面试官可能会追问"如何提高反射性能?"答:可以通过缓存
Method、Field等对象减少重复获取的开销。