未定事件簿官服手游
314.22MB · 2025-09-23
下面是一篇基于最新 JDK 实践,内容涵盖:概念 → 基本 API → JDK 9+ 变化 → 安全与性能 → 最佳实践,并附示例代码。
反射(Reflection) 是 Java 提供的一种机制,允许程序在运行时动态地:
它打破了编译期的静态类型限制,使框架(如 Spring、MyBatis)能够实现依赖注入、ORM 映射等功能。
反射主要位于 java.lang.reflect
包,核心类包括:
Class<T>
:类型元信息入口Field
:字段Method
:方法Constructor<T>
:构造器Class
对象Class<?> clazz1 = String.class;
Class<?> clazz2 = "Hello".getClass();
Class<?> clazz3 = Class.forName("java.lang.String");
推荐:
MyClass obj = MyClass.class.getDeclaredConstructor().newInstance();
原因:
ReflectiveOperationException
)Field f = MyClass.class.getDeclaredField("name");
f.setAccessible(true); // 破私有(需注意模块限制)
f.set(obj, "Ocean");
System.out.println(f.get(obj));
Method m = MyClass.class.getDeclaredMethod("sayHello", String.class);
m.setAccessible(true);
String result = (String) m.invoke(obj, "World");
System.out.println(result);
--add-opens
:java --add-opens java.base/java.lang=ALL-UNNAMED ...
module-info.java
中显式 opens
。性能开销:反射调用比直接调用慢 10~20 倍(JIT 优化后仍有差距)。
安全风险:setAccessible(true)
绕过封装,可能破坏模块边界。
最佳实践:
MethodHandle
(Java 7+)或 VarHandle
(Java 9+)替代,性能更好。实例化
clazz.getDeclaredConstructor().newInstance();
跨模块访问
--add-opens
或 module-info.java
的 opens
。性能敏感场景
MethodHandle
:MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.findVirtual(MyClass.class, "sayHello",
MethodType.methodType(String.class, String.class));
String result = (String) mh.invoke(obj, "World");
避免滥用反射
public class ReflectionDemo {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("com.example.MyClass");
Object obj = clazz.getDeclaredConstructor().newInstance();
Method m = clazz.getDeclaredMethod("sayHello", String.class);
m.setAccessible(true);
String result = (String) m.invoke(obj, "Ocean");
System.out.println(result);
}
}