java反射机制获取对象中父类属性对象

今天有朋友问,继承会继承父类的私有属性和私有方法吗。回答当然是可以的,只是不能直接访问(例如对于父类的私有属性,可以借助从父类中继承的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);
        }
    }
}

参考

Java反射机制获取父类属性: https://www.jianshu.com/p/6fe3e0e185ac

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
通过Java反射机制,可以通过子类对象获取子类及父类的所有属性。可以使用 `Class.getDeclaredFields()` 方法来获取一个类的所有属性,包括私有属性。同时,需要使用 `Class.getSuperclass()` 方法来获取父类的Class对象,然后再获取父类属性。下面是一个示例代码: ```java import java.lang.reflect.Field; public class Parent { private int parentField; // 省略getter和setter方法 } public class Child extends Parent { private int childField; // 省略getter和setter方法 } public class Main { public static void main(String[] args) throws Exception { Child child = new Child(); child.setParentField(1); child.setChildField(2); // 获取子类的属性 Field[] childFields = child.getClass().getDeclaredFields(); for (Field field : childFields) { field.setAccessible(true); System.out.println("Child field: " + field.getName() + " = " + field.get(child)); } // 获取父类属性 Field[] parentFields = child.getClass().getSuperclass().getDeclaredFields(); for (Field field : parentFields) { field.setAccessible(true); System.out.println("Parent field: " + field.getName() + " = " + field.get(child)); } } } ``` 在上述代码,我们首先创建了一个Child对象,然后通过反射机制获取了子类的所有属性父类的所有属性。注意,我们需要使用 `Field.setAccessible(true)` 方法来设置属性可访问,否则私有属性无法访问。运行上述代码,即可看到子类及父类的所有属性值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值