如何反射获取Field
在 Java 中,可以通过**反射(Reflection)**来获取类的 Field(字段)。下面按常见场景给你一个完整说明。
一、获取 Class 对象(前提)
反射的第一步是拿到 Class 对象:
Class> clazz = MyClass.class;
// 或
Class> clazz = Class.forName("com.example.MyClass");
// 或
Class> clazz = obj.getClass();
二、获取 Field 的常用方法
1️⃣ 获取所有 public 字段(包括继承的)
Field[] fields = clazz.getFields();
✅ 只能获取 public
✅ 包含父类 public 字段
2️⃣ 获取某个指定的 public 字段
Field field = clazz.getField("name");
3️⃣ 获取本类声明的所有字段(不包含继承)
Field[] fields = clazz.getDeclaredFields();
✅ 不限访问权限(private / protected / public)
❌ 不包含父类字段
4️⃣ 获取某个指定字段(无论访问权限)
Field field = clazz.getDeclaredField("age");
三、访问(读写)Field 的值
示例类
class Person {
private String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
1️⃣ 读取字段值
Person p = new Person("Tom", 18);
Field ageField = Person.class.getField("age");
int age = (int) ageField.get(p);
System.out.println(age); // 18
2️⃣ 修改 public 字段
ageField.set(p, 20);
3️⃣ 访问 private 字段(关键)
Field nameField = Person.class.getDeclaredField("name");
// 解除私有限制
nameField.setAccessible(true);
String name = (String) nameField.get(p);
System.out.println(name); // Tom
nameField.set(p, "Jerry");
⚠️ 注意:
setAccessible(true)可能受 Java 模块化 / SecurityManager 限制- 在 Java 9+ 中访问模块私有字段可能抛异常
四、获取字段信息(常用 API)
Field field = Person.class.getDeclaredField("name");
System.out.println(field.getName()); // 字段名
System.out.println(field.getType()); // 字段类型
System.out.println(Modifier.toString(field.getModifiers())); // 修饰符
五、静态字段的访问
class Config {
public static String VERSION = "1.0";
}
Field field = Config.class.getField("VERSION");
String version = (String) field.get(null); // 静态字段,obj 传 null
六、常见异常
| 异常 | 原因 |
|---|---|
NoSuchFieldException |
字段不存在 |
IllegalAccessException |
未设置 setAccessible(true) |
ClassCastException |
类型转换错误 |
七、总结(速查)
// 获取字段
clazz.getField(name); // public
clazz.getDeclaredField(name); // 任意访问权限
// 访问私有字段
field.setAccessible(true);
field.get(obj);
field.set(obj, value);
如果你有具体场景(如:Spring、注解处理、泛型字段、Kotlin、Android),可以告诉我,我可以给你更贴近实战的示例。