当前位置:首页 > Java技术 > Java反射获取父类中的元素

Java反射获取父类中的元素

2022年11月09日 15:33:18Java技术7

我们知道,可以通过getDeclaredField和getField方法可以反射获取class中的元素,他们的区别在于getField只能访问公有变量,而getDeclaredField则可以访问定义的所有变量,包括protected修饰和private修饰的变量。

    // 1.getDeclaredField方法调用searchFields方法
    Field field = searchFields(privateGetDeclaredFields(false), name);

    // 2.getField方法剪接调用searchFields方法
    if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {
        return res;
    }

不过,若要访问父类中的元素,通过getDeclaredField和getField方法就会抛出NoSuchFieldException异常了。也就是说,无法直接用java.lang.Class中的方法去访问父类中的元素。Spring中的工具类org.springframework.util.ReflectionUtils提供了findField方法,能够取得父类中的元素。我们看一下其中的实现:

    public static Field findField(Class<?> clazz, String name, Class<?> type) {
     
        Assert.notNull(clazz, "Class must not be null");
        Assert.isTrue(name != null || type != null, "Either name or type of the field must be specified");
        Class<?> searchType = clazz;
        while (!Object.class.equals(searchType) && searchType != null) {
            // 这里一次性获取了类中的所有元素
            Field[] fields = searchType.getDeclaredFields();
            for (Field field : fields) {
                if ((name == null || name.equals(field.getName())) && (type == null || type.equals(field.getType()))) {
                    return field;
                }
            }
            // 获取所有父类,接着遍历父类中的元素。
            searchType = searchType.getSuperclass();
        }
        return null;
    }

笔者本希望通过getDeclaredField()方法直接反射获取class中的元素,不过为了获取其父类中的元素使用了工具类ReflectionUtils。我们通过计算getDeclaredField()方法和ReflectionUtils.findField()方法在1秒内获取类中元素的次数来判断两者的性能。

    public static void main(String[] args) {
        try {
            int times = 0;
            long startMili = System.currentTimeMillis();
            while (true) {
                long nowMili = System.currentTimeMillis();
                InteBidResultDTO.class.getDeclaredField("balance");
                times++;
                if (nowMili > startMili + 1000) {
                    break;
                }
            }
            System.out.println("getDeclaredField方法执行了" + times + "次");
            times = 0;
            startMili = System.currentTimeMillis();
            while (true) {
                long nowMili = System.currentTimeMillis();
                ReflectionUtils.findField(InteBidResultDTO.class, "balance");
                times++;
                if (nowMili > startMili + 1000) {
                    break;
                }
            }
            System.out.println("findField方法执行了" + times + "次");
        } catch (SecurityException | NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

运行结果是:
getDeclaredField方法执行了3200996次
findField方法执行了2434921次

由于ReflectionUtils.findField()方法会去查找父类中的元素,性能必然会差一些。如果一个类的父类祖先越多,遍历次数也就越多,上述运行结果的差距也就更加明显。

作者:盖世胖胖
来源链接:https://blog.csdn.net/peerless_hero/article/details/54141623

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/java/68811.html

分享给朋友:

“Java反射获取父类中的元素” 的相关文章

Java空指针异常解决java.lang.NullPointerException解决心得

Java空指针异常解决java.lang.NullPointerException解决心得

今天做课设的时候运行程序报出以下错误 java.lang.NullPointerException 首先要理解的是此错误并不会在 程序中报错,只会在运行的时候报错。 是由于某个参数(集合,数组等数据)可能出现一个null值而导致后面的程序不能运行时...

java之整数的分解可以理解为倒序输出

Scanner in=new Scanner(System.in); int number ; number=in.nextInt(); int result=0; do{ int diget=number%10;...

Java对象的大小

基本数据的类型的大小是固定的,这里就不多说了。对于非基本类型的Java对象,其大小就值得商榷。 在Java中,一个空Object对象的大小是8byte,这个大小只是保存堆中一个没有任何属性的对象的大小。看 下面语句: Object ob = new Ob...

Java实现ModbusTCP通信

Java实现ModbusTCP通信

使用ModbusTCP实现和硬件设备通信 有问题可以私信和评论,看到会回复。 一个项目,需要用Java实现使用ModbusTCP和硬件设备通信 视频地址:https://www.bilibili.com/video/BV1cz4y1R7cg...

JAVA的文件操作【转】

11.3 I/O类使用          由于在IO操作中,需要使用的数据源有很多,作为一个IO技术的初学者,从读写文件开始学习IO技术是一个比较好的选择。因为文件是一种常见的数据源,而且读写文件也是程...

Java并发之AQS详解

Java并发之AQS详解

java、多线程、并发、AbstractQueuedSynchronized、AQS、Lock、Mutex、ReentrantLock、Semaphore、CountDownLatch、线程同步 一、概述   谈到并发,不得不谈ReentrantLock;而谈到...

java IO流学习总结

java IO流学习总结

java IO流学习总结 近期学习了Java的IO流,尝试着总结一下。 java.io 包下的IO流很多: 其中,以Stream结尾的为字节流,以Writer或者Reader结尾的为字符流。所有的输入流都是抽象类IuputStream(字节输入流)或者抽象类R...

Java并发包基石

Java并发包基石

目录     1 基本实现原理       1.1 如何使用        1.2 设计思想     2 自定义同步器       2.1 同步器代码实现        2.2 同步器代码测试     3 源码分析       ...

JavaWeb(一)之细说Servlet

JavaWeb(一)之细说Servlet

前言   其实javaWeb的知识早就学过了,可是因为现在在搞大数据开发,所以web的知识都忘记了。准备开始慢慢的把Web的知识一点一点的回忆起来,多学一点没有关系,就怕到时候要用的话,什么都不会了。 一、Servlet概述 1.1、Servlet简介   Se...

狂神Java基础总结

狂神Java基础总结

Java基础 Java学习的正确打开方式 学习是一个过程,是一个不断累积、不断沉淀、不断总结、善于传达自己的个人见解以及乐于分享的过程。 链接:https://blog.csdn.net/qq_44543508/article/details/102651841...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。