Java字段反射
通过反射获取和操作字段,实现动态属性访问。
获取字段
获取公共字段
Java
Class<?> clazz = Person.class;
// 获取所有公共字段(包括继承的)
Field[] publicFields = clazz.getFields();
// 获取指定名称的公共字段
Field field = clazz.getField("name");
获取所有字段(包括私有)
Java
// 获取本类声明的所有字段(不含继承)
Field[] declaredFields = clazz.getDeclaredFields();
// 获取指定名称的字段(包括私有)
Field privateField = clazz.getDeclaredField("age");
读写字段值
获取和设置字段值
Java
Person person = new Person();
Class<?> clazz = person.getClass();
// 获取字段
Field nameField = clazz.getDeclaredField("name");
// 获取字段值
Object value = nameField.get(person);
// 设置字段值
nameField.set(person, "张三");
字段类型操作
Java
Field field = clazz.getDeclaredField("age");
// 获取值(按类型)
int intValue = field.getInt(person);
Object objValue = field.get(person);
// 设置值(按类型)
field.setInt(person, 25);
field.set(person, 30);
完整示例
Java
public class Person {
public String name;
private int age;
private static String country = "China";
public Person() {}
public void printInfo() {
System.out.println(name + ", " + age);
}
}
// 反射操作字段
Class<?> clazz = Person.class;
Person person = new Person();
// 操作公共字段
Field nameField = clazz.getField("name");
nameField.set(person, "李四");
String name = (String) nameField.get(person);
// 操作私有字段
Field ageField = clazz.getDeclaredField("age");
ageField.setAccessible(true); // 暴力反射
ageField.set(person, 30);
int age = ageField.getInt(person);
// 操作静态字段
Field countryField = clazz.getDeclaredField("country");
countryField.setAccessible(true);
countryField.set(null, "中国"); // 静态字段,对象传null
String country = (String) countryField.get(null);
Field常用方法
Java
Field field = clazz.getDeclaredField("name");
// 字段信息
String name = field.getName(); // 字段名
Class<?> type = field.getType(); // 字段类型
int modifiers = field.getModifiers(); // 修饰符
// 获取值
Object value = field.get(obj);
int intValue = field.getInt(obj);
long longValue = field.getLong(obj);
boolean boolValue = field.getBoolean(obj);
// 设置值
field.set(obj, value);
field.setInt(obj, intValue);
field.setLong(obj, longValue);
field.setBoolean(obj, boolValue);
getFields与getDeclaredFields区别
| 方法 | 范围 | 访问权限 | 继承字段 |
|---|---|---|---|
| getFields() | 本类+父类+接口 | 仅public | 包含 |
| getDeclaredFields() | 仅本类 | 所有 | 不含 |
常见字段类型判断
Java
Field field = clazz.getDeclaredField("name");
Class<?> type = field.getType();
// 类型判断
if (type == String.class) {
// 字符串类型
} else if (type == int.class || type == Integer.class) {
// 整型
} else if (type.isPrimitive()) {
// 基本类型
} else if (type.isArray()) {
// 数组类型
Class<?> componentType = type.getComponentType();
}
注意事项
私有字段必须 setAccessible(true) 才能访问和修改
静态字段操作时,get/set 方法的对象参数传 null
final 字段修改需要特殊处理,且在JDK 9+受到模块系统限制
反射修改字段会破坏封装,应谨慎使用
要点总结
- getField() 获取公共字段,getDeclaredField() 获取所有字段
- 使用 field.get(obj) 获取值,field.set(obj, value) 设置值
- 私有字段需要 setAccessible(true) 突破访问限制
- 静态字段操作时对象参数传 null
- 提供了类型安全的 getXXX/setXXX 方法
📝 发现内容有误?点击此处直接编辑