访问字段
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()
:返回字段名称,例如,name
getType()
:返回字段类型,也是一个Class实例,例如,String.class
getModifiers()
:返回字段的修饰符,它是一个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;
}
}