访问字段
约 713 字大约 2 分钟
2024-08-10
对任意的一个 Object 实例,只要我们获取了它的 Class,就可以获取它的一切信息
Class类提供了以下几个方法来获取字段
Field getField(name):根据字段名获取某个public的field(包括父类)Field getDeclaredField(name):根据字段名获取当前类的某个field(不包括父类)Field[] getFields():获取所有public的field(包括父类)Field[] getDeclaredFields():获取当前类的所有field(不包括父类)
public class Main {
public static void main(String[] args) throws Exception {
Class stdClass = Student.class;
// // 获取 public 字段 "score"
System.out.println(stdClass.getField("score"));
// 获取继承的 public 字段 "name"
System.out.println(stdClass.getField("name"));
// 获取 private 字段 "grade"
System.out.println(stdClass.getDeclaredField("grade"));
}
}
class Student extends Person {
public int score;
private int grade;
}
class Person {
public String name;
}上述代码首先获取 Student 的 Class 实例,然后,分别获取 public 字段、继承的 public 字段以及 private 字段,打印出的 Field
public int com.marui.reflection.Student.score
public java.lang.String com.marui.reflection.Person.name
private int com.marui.reflection.Student.grade一个 Field 对象包含了一个字段的所有信息
getName():返回字段名称,例如,namegetType():返回字段类型,也是一个Class实例,例如,String.classgetModifiers():返回字段的修饰符,它是一个int,不同的bit表示不同的含义
以 String 类的 value 字段为例,它的定义是
public final class String {
private final char value[];
}反射获取该字段的信息,代码如下
Field f = String.class.getDeclaredField("value");
f.getName(); // value
f.getType(); // class [C , 表示char[]类型
int m = f.getModifiers();
Modifier.isFinal(m); // true
Modifier.isPublic(m); // false
Modifier.isProtected(m); // false
Modifier.isPrivate(m); // true
Modifier.isStatic(m); // false获取字段值
利用反射拿到字段的一个 Field 实例只是第一步,我们还可以拿到一个实例对应的该字段的值
public class Main {
public static void main(String[] args) throws Exception {
Person p = new Person("张三");
// 获取 Person 对应的 Class 实例
Class pClass = p.getClass();
// 获取指定 Class 实例指定的字段值
Field fName = pClass.getDeclaredField("name");
// 访问时会忽略访问修饰符的检查,如果不设置访问 private 修饰字段将抛出 IllegalAccessException 异常
fName.setAccessible(true);
// 获取指定对象的当前字段值
Object value = fName.get(p);
System.out.println(value); // 张三
}
}
class Person {
public String name;
public Person(String name) {
this.name = name;
}
}设置字段值
设置字段值是通过 Field.set(Object, Object) 实现的,其中第一个 Object 参数是指定的实例,第二个 Object 参数是待修改的值
public class Main {
public static void main(String[] args) throws Exception {
Person p = new Person("张三");
// 获取 Person 对应的 Class 实例
Class pClass = p.getClass();
// 获取指定 Class 实例指定的字段值
Field fName = pClass.getDeclaredField("name");
// 访问时会忽略访问修饰符的检查,如果不设置访问 private 修饰字段将抛出 IllegalAccessException 异常
fName.setAccessible(true);
// 设置指定对象字段的值
fName.set(p, "李四");
System.out.println(p.getName()); // 李四
}
}
class Person {
public String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}