Java 反射
Class 对象的获取、动态创建实例、调用方法与访问字段。
获取 Class 对象
Three routes: Type.class (known at compile time, safest), obj.getClass(), and Class.forName("fqcn") for configuration-driven loading — the last may throw ClassNotFoundException.
public class GetClass {
public static void main(String[] args) throws Exception {
Class<?> a = String.class;
Class<?> b = "x".getClass();
Class<?> c = Class.forName("java.lang.String");
System.out.println(a == b);
System.out.println(b == c);
System.out.println(a.getSimpleName());
System.out.println(a.getPackageName());
}
}true
true
String
java.lang创建实例与调用方法
getDeclaredConstructor().newInstance() constructs an object; getMethod finds public methods, getDeclaredMethod any declared in the class (private included), and invoke runs them.
import java.lang.reflect.Method;
public class InvokeDemo {
public static void main(String[] args) throws Exception {
Class<?> c = Class.forName("java.lang.String");
Object s = c.getConstructor(String.class).newInstance("hello");
Method m = c.getMethod("toUpperCase");
System.out.println(s);
System.out.println(m.invoke(s));
System.out.println(m.getReturnType().getSimpleName());
}
}hello
HELLO
String访问私有成员
getDeclaredField reaches private fields, but you must call setAccessible(true) first. Since Java 17 strong encapsulation blocks this unless the module opens up.
import java.lang.reflect.Field;
class Secret {
private String value = "hidden";
}
public class PrivateAccess {
public static void main(String[] args) throws Exception {
Secret s = new Secret();
Field f = Secret.class.getDeclaredField("value");
f.setAccessible(true);
System.out.println(f.get(s));
f.set(s, "changed");
System.out.println(f.get(s));
}
}hidden
changed获取 Class 对象
三种方式:类名.class(编译期已知、最安全)、对象.getClass()、Class.forName("全限定名")(配置驱动、可能抛 ClassNotFoundException)。
public class GetClass {
public static void main(String[] args) throws Exception {
Class<?> a = String.class;
Class<?> b = "x".getClass();
Class<?> c = Class.forName("java.lang.String");
System.out.println(a == b);
System.out.println(b == c);
System.out.println(a.getSimpleName());
System.out.println(a.getPackageName());
}
}true
true
String
java.lang创建实例与调用方法
getDeclaredConstructor().newInstance() 创建对象,getMethod 取公开方法、getDeclaredMethod 取本类声明的(含 private),invoke 执行。
import java.lang.reflect.Method;
public class InvokeDemo {
public static void main(String[] args) throws Exception {
Class<?> c = Class.forName("java.lang.String");
Object s = c.getConstructor(String.class).newInstance("hello");
Method m = c.getMethod("toUpperCase");
System.out.println(s);
System.out.println(m.invoke(s));
System.out.println(m.getReturnType().getSimpleName());
}
}hello
HELLO
String访问私有成员
getDeclaredField 能拿到 private 字段,但要先 setAccessible(true) 才能读写。Java 17 起强封装模块会阻止这种做法,除非显式开放。
import java.lang.reflect.Field;
class Secret {
private String value = "hidden";
}
public class PrivateAccess {
public static void main(String[] args) throws Exception {
Secret s = new Secret();
Field f = Secret.class.getDeclaredField("value");
f.setAccessible(true);
System.out.println(f.get(s));
f.set(s, "changed");
System.out.println(f.get(s));
}
}hidden
changed