1、在 java.lang.reflect
下有个 Field
类,因为反射是通过Class类得到的,所以访问字段的方法是在Class类中的方法,得到的类型都是Field类型,一共有四种方法:
- 获取单个
public 属性
的字段(包含父类)Field getField(name)
- 获取单个字段(不包含父类)
Field getDeclaredField(name)
- 获取所有
public属性
的字段(包含父类)Field[] getFields()
- 获取所有字段(不包含父类)
Field[] getDeclaredFields()
package reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class GetField {
public static void main(String[] args) throws Exception {
System.out.println("-----------下面是测试获取字段方法------------");
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"));
Field f[] = stdClass.getFields();
for(int i = 0; i < f.length; i++){
System.out.println("Public Fields is " +f[i].toString());
}
Field f2[] = stdClass.getDeclaredFields();
for(int i = 0; i < f2.length; i++){
System.out.println("the current class has " + f2[i].toString());
}
}
}
class Student extends Person {
public int score;
private int grade;
public Student(String name){
super(name);
}
}
class Person {
public String name;
public Person(String name){
this.name = name;
}
}
2、Field对象包含一个字段所有的信息
- getName()方法 返回字段的名称
- getType()方法 返回字段的类型,也是一个Class类型
- getModifier()方法 返回字段的修饰符,值是一个
int
(final,private, public, protected),通过Modifier类中的方法来判断
package reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class GetField {
public static void main(String[] args) throws Exception {
System.out.println("--------------下面是测试Field对象的内容-----------------");
Field f3 = stdClass.getField("score");
System.out.println(f3.getName());
System.out.println(f3.getType());
//getModifiers 返回的类型是 int 型,通过 bit 位来确定是哪些类型
int m = f3.getModifiers();
System.out.println(m);
System.out.println(Modifier.isPublic(m));
}
}
class Student extends Person {
public int score;
private int grade;
public Student(String name){
super(name);
}
}
class Person {
public String name;
public Person(String name){
this.name = name;
}
}
3、获取一个字段的值
流程如下:
- 通过 getClass() 反射得到Class实例
- 通过 getField() 得到 Field实例
- 通过 Field.get(Object) 得到指定实例(第一步)的指定字段(第二步)的值,注意修改非public字段要先设置访问权限
Field.setAccessible(true);
package reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class GetField {
public static void main(String[] args) throws Exception {
System.out.println("-----------下面测试获取字段的值----------");
Student student = new Student("Xiao Ming");
Class stuClass = student.getClass();
Field f4 = stuClass.getField("name");
f4.setAccessible(true);
Object value = f4.get(student);
System.out.println(value);
}
}
class Student extends Person {
public int score;
private int grade;
public Student(String name){
super(name);
}
}
class Person {
public String name;
public Person(String name){
this.name = name;
}
}
4、设置一个字段的值
这个地方与获取到一个字段的值类似,最后通过调用 Field.set(Object obj1, Object obj2);
来设置,其中obj1是被修改对象,obj2是修改的内容
package reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class GetField {
public static void main(String[] args) throws Exception {
System.out.println("----------下面测试设置字段的值----------");
Male male = new Male();
male.setName("Li Hua");
Class maleClass = male.getClass();
Field f5 = maleClass.getDeclaredField("name");
f5.setAccessible(true);
Object male1Value = f5.get(male);
System.out.println("改之前的值:" + male1Value);
f5.set(male, "Zhang San");
Object male2Value = f5.get(male);
System.out.println("改之后的值:" + male2Value);
System.out.println("判断改之后两个值是否相等:" + male1Value.equals(male2Value));
}
class Male{
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}