反射 调用方法/获取属性/

今天有朋友问,继承会继承父类的私有属性和私有方法吗。回答当然是可以的,只是不能直接访问(例如对于父类的私有属性,可以借助从父类中继承的get方法来获得该值)。

当时也想到可以通过反射的方式来获取父类中私有属性的值。一开始使用getDeclaredFileds(),但发现只能获取子类的相关的属性对象,后面结合getSuperclass()方法先获取父类的字节码对象进而获取了子类中的所有属性对象。具体代码如下:

通过 getDeclaredFileds()方法获取属性对象
父类:

public class Person {
public String name;
private int age;
}
子类:

public class Student extends Person {
public String className;
private String gender;
}
测试:

public class Demo {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Student student = new Student();

    // 通过子类的字节码对象获取获取所有属性
    Class<Student> studentClass = Student.class;
    Field[] declaredFields = studentClass.getDeclaredFields();

    for (Field declaredField : declaredFields) {  // 打印所有的属性字段
        System.out.println(declaredField);
    }
}

}
运行结果:

public java.lang.String Demo.Student.className
private java.lang.String Demo.Student.gender
可以看到通过getDeclaredFileds()方法可以获取当前类私有属性对象和公有属性对象,当不能获取父类相关的属性对象。

结合getSuperclass()方法获取父类的属性对象
由于反射机制只能获取当前类的属性对象,为了获取其父类的属性对象就需要先通过getSuperclass获取该当前类的父类字节码对象,因为类存在对继承这里使用了while(clazz != null)遍历了所有的父类字节码对象。具体代码如下:

public class Demo {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Student student = new Student();

    Class clazz = Student.class;
    List fieldsList = new ArrayList<Field[]>();  // 保存属性对象数组到列表
    while (clazz != null) {  // 遍历所有父类字节码对象
        Field[] declaredFields = clazz.getDeclaredFields();  // 获取字节码对象的属性对象数组
        fieldsList.add(declaredFields);

        clazz = clazz.getSuperclass();  // 获得父类的字节码对象
    }

    for (Object fields:fieldsList) {  // 打印当前类以及其父类的多有属性对象
        Field[] f = (Field[]) fields;
        for (Field field : f) {
            System.out.println(field);
        }
    }
}

}
结果:

public java.lang.String Demo.Student.className
private java.lang.String Demo.Student.gender
public java.lang.String Demo.Person.name
private int Demo.Person.age
上述代码还可以进行改进,可以将Filed[]数组转换为List<>然后再将其拼接至ArrayList上,这样后面遍历Filed对象也不用嵌套循环了。

public class Demo {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Student student = new Student();

    Class clazz = Student.class;
    List fieldsList = new ArrayList<Field>();
    while (clazz != null) {  // 遍历所有父类字节码对象
        Field[] declaredFields = clazz.getDeclaredFields();
        fieldsList.addAll(Arrays.asList(declaredFields));  //将`Filed[]`数组转换为`List<>`然后再将其拼接至`ArrayList`上

        clazz = clazz.getSuperclass();  // 获得父类的字节码对象
    }

    for (Object field : fieldsList) {  // 打印当前类以及其父类的多有属性对象
        System.out.println(field);
    }
}

}

猜你喜欢

转载自blog.csdn.net/javahelpyou/article/details/113935995