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

本文详细介绍了如何利用Java反射机制获取父类的私有属性和方法,包括使用getDeclaredFields()和getSuperclass()方法的具体步骤,以及如何遍历所有父类的字节码对象以获取完整的属性列表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值