怎样提高使用Java反射的效率
在我们平时的工作或者面试中,都会经常遇到“反射”这个知识点,通过“反射”我们可以动态的获取到对象的信息以及灵活的调用对象方法等,但是在使用的同时又伴随着另一种声音的出现,那就是“反射”很慢,要少用。难道反射真的很慢?那跟我们平时正常创建对象调用方法比慢多少? 估计很多人都没去测试过,只是”道听途说“。下面我们就直接通过一些测试用例来直观的感受一下”反射“。
正文
准备测试对象
下面先定义一个测试的类TestUser,只有id跟name属性,以及它们的getter/setter方法,另外还有一个自定义的sayHi方法。
public class TestUser { private Integer id; private String name; public String sayHi(){ return "hi"; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
测试创建100万个对象
// 通过普通方式创建TestUser对象@Testpublic void testCommon(){ long start = System.currentTimeMillis(); TestUser user = null; int i = 0; while(i<1000000){ ++i; user = new TestUser(); } long end = System.currentTimeMillis(); System.out.println("普通对象创建耗时:"+(end - start ) + "ms"); }//普通对象创建耗时:10ms
// 通过反射方式创建TestUser对象@Testpublic void testReflexNoCache() throws Exception { long start = System.currentTimeMillis(); TestUser user = null; int i = 0; while(i<1000000){ ++i; user = (TestUser) Class.forName("ReflexDemo.TestUser").newInstance(); } long end = System.currentTimeMillis(); System.out.println("无缓存反射创建对象耗时:"+(end - start ) + "ms"); }//无缓存反射创建对象耗时:926ms
在上面这两个测试方法中,笔者各自测了5次,把他们消耗的时间取了一个平均值,在输出结果中可以看到一个是10ms,一个是926ms,在创建100W个对象的情况下,反射居然慢了90倍左右。wtf?差距居然这么大?难道反射真的这么慢?下面笔者换一种反射的姿势,继续测试一下,看看结果如何?
// 通过缓存反射方式创建TestUser对象@Testpublic void testReflexWithCache() throws Exception { long start = System.currentTimeMillis(); TestUser user = null; Class rUserClass = Class.forName("RefleDemo.TestUser"); int i = 0; while(i<1000000){ ++i; user = (TestUser) rUserClass.newInstance(); } long end = System.currentTimeMillis(); System.out.println("通过缓存反射创建对象耗时:"+(end - start ) + "ms"); }//通过缓存反射创建对象耗时:41ms
其实通过代码我们可以发现,是Class.forName这个方法比较耗时,它实际上调用了一个本地方法,通过这个方法来要求JVM查找并加载指定的类。所以我们在项目中使用的时候,可以把Class.forName返回的Class对象缓存起来,下一次使用的时候直接从缓存里面获取,这样就极大的提高了获取Class的效率。同理,在我们获取Constructor、Method等对象的时候也可以缓存起来使用,避免每次使用时再来耗费时间创建。
测试反射调用方法
@Testpublic void testReflexMethod() throws Exception { long start = System.currentTimeMillis(); Class testUserClass = Class.forName("RefleDemo.TestUser"); TestUser testUser = (TestUser) testUserClass.newInstance(); Method method = testUserClass.getMethod("sayHi"); int i = 0; while(i<100000000){ ++i; method.invoke(testUser); } long end = System.currentTimeMillis(); System.out.println("反射调用方法耗时:"+(end - start ) + "ms"); }//反射调用方法耗时:330ms
@Testpublic void testReflexMethod() throws Exception { long start = System.currentTimeMillis(); Class testUserClass = Class.forName("RefleDemo.TestUser"); TestUser testUser = (TestUser) testUserClass.newInstance(); Method method = testUserClass.getMethod("sayHi"); int i = 0; while(i<100000000){ ++i; method.setAccessible(true); method.invoke(testUser); } long end = System.currentTimeMillis(); System.out.println("setAccessible=true 反射调用方法耗时:"+(end - start ) + "ms"); }//setAccessible=true 反射调用方法耗时:188ms
这里我们反射调用sayHi方法1亿次,在调用了method.setAccessible(true)后,发现快了将近一半。查看API可以了解到,jdk在设置获取字段,调用方法的时候会执行安全访问检查,而此类操作会比较耗时,所以通过setAccessible(true)的方式可以关闭安全检查,从而提升反射效率。
极致的反射
除了上面的手段,还有没有什么办法可以更极致的使用反射呢?这里介绍一个高性能反射工具包ReflectASM。它是通过字节码生成的方式来实现的反射机制,下面是一个跟java反射的性能比较。
结语
最后总结一下,为了更好的使用反射,我们应该在项目启动的时候将反射所需要的相关配置及数据加载进内存中,在运行阶段都从缓存中取这些元数据进行反射操作。大家也不用惧怕反射,虚拟机在不断的优化,只要我们方法用的对,它并没有”传闻“中的那么慢,当我们对性能有极致追求的时候,可以考虑通过三方包,直接对字节码进行操作。
相关教程:Java视频教程
以上是怎样提高使用Java反射的效率的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

DeepMind的AI智能体,又来卷自己了!注意看,这个名叫BBF的家伙,只用2个小时,就掌握了26款雅达利游戏,效率和人类相当,超越了自己一众前辈。要知道,AI智能体通过强化学习解决问题的效果一直都不错,但最大的问题就在于这种方式效率很低,需要很长时间摸索。图片而BBF带来的突破正是在效率方面。怪不得它的全名可以叫Bigger、Better、Faster。而且它还能只在单卡上完成训练,算力要求也降低许多。BBF由谷歌DeepMind和蒙特利尔大学共同提出,目前数据和代码均已开源。最高可取得人类

PyCharm是一款功能强大的Python集成开发环境(IDE),广泛用于Python开发者进行代码编写、调试和项目管理。在实际的开发过程中,大多数开发者都会面临不同的问题,比如如何提升开发效率、如何与团队成员进行协作开发等。本文将介绍PyCharm远程开发的实用指南,帮助开发者更好地利用PyCharm进行远程开发,提高工作效率。1.准备工作在进行PyCh

StableDiffusion是一个开源的深度学习模型,其主要功能是通过文本描述来生成高质量的图像,并支持图生成、模型合并、以及模型训练等功能。该模型的操作界面可以在下图中看到。如何生图下面介绍一下小鹿喝水的生图过程,生成图的时候分为提示词和负面提示词,输入提示词的时候要明确描述,尽量具体描述你想要的场景、对象、风格和颜色。例如,不仅仅说“小鹿喝水”,而是说“一条小溪,旁边是茂密的树,小溪旁有小鹿在喝水”,负面提示词是反方向的例如:无建筑物、无人物、无桥梁、无围栏,而过于模糊的描述可能导致结果不

Java反射是一个强大的工具,它可以让你访问类的私有字段和方法,从而揭秘软件的内部运作方式。这在逆向工程、软件分析和调试等领域非常有用。要使用Java反射,首先需要导入java.lang.reflect包。然后,你可以使用Class.forName()方法来获取一个类的Class对象。一旦有了Class对象,你就可以使用各种方法来访问类的字段和方法。例如,你可以使用getDeclaredFields()方法来获取类的所有字段,包括私有字段。你也可以使用getDeclaredMethods()方法

随着互联网的快速发展,数据库的重要性日益凸显。作为一名Java开发者,我们经常会涉及到数据库操作,数据库事务处理的效率直接关系到整个系统的性能和稳定性。本文将介绍一些Java开发中常用的优化数据库事务处理效率的技巧,帮助开发者提高系统的性能和响应速度。批量插入/更新操作通常情况下,一次向数据库中插入或更新单条记录的效率远低于批量操作。因此,在进行批量插入/更

标题:Python让生活更便捷:掌握这门语言,提升工作效率和生活品质Python作为一种强大而简单易学的编程语言,在当今的数字化时代越来越受到人们的青睐。不仅仅用于编写程序和进行数据分析,Python还可以在我们的日常生活中发挥巨大的作用。掌握这门语言,不仅能提升工作效率,还能提高生活品质。本文将通过具体的代码示例,展示Python在生活中的广泛应用,帮助读

掌握sessionStorage的作用,提升前端开发效率,需要具体代码示例随着互联网的快速发展,前端开发领域也日新月异。在进行前端开发时,我们经常需要处理大量的数据,并将其存储在浏览器中以便后续使用。而sessionStorage就是一种非常重要的前端开发工具,可以为我们提供临时的本地存储解决方案,提高开发效率。本文将介绍sessionStorage的作用,

子网掩码的作用及其对网络通信效率的影响引言:随着互联网的普及,网络通信成为现代社会中不可或缺的一部分。与此同时,网络通信的效率也成为了人们关注的焦点之一。在构建和管理网络的过程中,子网掩码是一项重要而且基础的配置选项,它在网络通信中起着关键的作用。本文将介绍子网掩码的作用,以及它对网络通信效率的影响。一、子网掩码的定义及作用子网掩码(subnetmask)
