zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Windows7,Ubuntu双系统,用MBR引导
    把Adblock Plus的过滤规则应用到IE9
    Linux shell学习
    vxworks下面网络连接调试的搭建
    uboot网卡成功识别
    uboot功能扩展篇
    uboot终于显示串口信息了
    uboot解决flash failed无限挂起的问题
    问题解决随笔
    琐事皆休,开始找工作~
  • 原文地址:https://www.cnblogs.com/bitbitbyte/p/12536575.html
Copyright © 2011-2022 走看看