其中主要分成两步:

1、根据属性名去类里面查找是否存在这个属性,并获取

2、如果存在属性,再从这个对象数据里面获取对应的值

在Class中里面有以下公共方法可以获取到类的属性:

public Field[] getDeclaredFields() throws SecurityException {...}
public Field getDeclaredField(String name){...}
public Field[] getFields() throws SecurityException {...}
public Field getField(String name){...} 

eg:

@Data
public class Student extends MyModel{
    String name;
    School school;

    public String publicName;
    public School publicSchool;

    private String privateName;
}
@Data
public class School {
    String name;
    String addr;
}
@Data
public class MyModel {
    Long id;
    public Long publicId;
}
public class Test1 {
    public static void main(String[] args) throws Exception{
        Student stu = new Student();
        stu.setName("yangcai");
        School sch = new School();
        sch.setAddr("张巷");
        sch.setName("中学");
        stu.setSchool(sch);
        try {
            Field[] fields = stu.getClass().getFields();
            for (Field f : fields){
                System.out.println("---getFields--"+f);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        try {
            Field field = stu.getClass().getField("name");
            System.out.println("---getFields--"+field);
        }catch (Exception e){
            e.printStackTrace();
        }
        try {
            Field field = stu.getClass().getDeclaredField("name");
            System.out.println("---getDeclaredFields--"+field);
        }catch (Exception e){
            e.printStackTrace();
        }
        try {
            Field[] fields = stu.getClass().getDeclaredFields();
            for (Field f : fields){
                System.out.println("---getDeclaredFields--"+f);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

 可见:

public Field[] getFields() throws SecurityException {...}
public Field getField(String name){...}

能获取到本类和父类的public属性

public Field[] getDeclaredFields() throws SecurityException {...}
public Field getDeclaredField(String name){...}

能获取到本类的所有声明的属性的 

 那有个疑问,因为getDeclaredFields只能获取本类Student 的所有的属性,getFields只能获取父类MyModel 的public属性,我要获取父类MyModel 的非public属性id,怎么办呢?

思路就是,通过本类,获取父类,在父类的基础上再使用getDeclaredFields去获取就可以了

        try {
            Field[] fields =  stu.getClass().getSuperclass().getDeclaredFields();
            for (Field f : fields){
                System.out.println("-superclass--getDeclaredFields--"+f);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

 获取到了field之后,我们就可以根据field去获取具体对象的的值了

public class Test1 {
    public static void main(String[] args) throws Exception{
        Student stu = new Student();
        stu.setName("yangcai");
        stu.setPrivateName("pyangcai");
        School sch = new School();
        sch.setAddr("张巷");
        sch.setName("中学");
        stu.setSchool(sch);
        try {
            Field field = stu.getClass().getDeclaredField("name");
            Object obj = field.get(stu);
            System.out.println("---field--"+field+"---value--"+obj);

            Field field1 = stu.getClass().getDeclaredField("publicName");
            Object obj1 = field1.get(stu);
            System.out.println("---field1--"+field1+"---value1--"+obj1);

            Field field2 = stu.getClass().getDeclaredField("privateName");
            field2.setAccessible(true);
            Object obj2 = field2.get(stu);
            System.out.println("---field2--"+field2+"---value2--"+obj2);

            Field field3 = stu.getClass().getDeclaredField("privateName");
            Object obj3 = field3.get(stu);
            System.out.println("---field3--"+field3+"---value3--"+obj3);

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

 由上述可知:通过反射获取私有属性的值要加field.setAccessible(true);否则会报错

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐