Java-如何提高JAVA反射机制创建对象的效率
Class clazz = Class.forName("Demo");
Object demo1 = clazz.getConstructor().newInstance();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
Class clazz = Class.forName("Demo");
Object demo1 = clazz.getConstructor().newInstance();
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(3)
为什么要调用一次构造方法呢
Oracle的官方文档里已经说了,反射API会慢一些。如果确实是性能要求比较高的应用,最好不要用发射。
http://docs.oracle.com/javase/tutorial/reflect/index.html
Performance Overhead
Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.
在Java中,反射是会比直接通过 new 创建对象实例来的慢,这是因为JVM 针对其做的优化,和直接创建对象是不一样的。但是下面是几个要注意的点
在最新版本的JVM上,反射的效率已经得到了比较大的提升。
Knuth说过,"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil" (http://en.wikipedia.org/wiki/Program_optimization) , Performance tuning必须是基于相应的应用场景,实际的测试数据和明确的优化目标而进行的。
在反射的执行过程中,对于类及对象的定义元数据的寻找效率是比其实际执行的效率低很多的,因此这里的瓶颈在于,如何一次性的,在配置而非运行时,将相关的元数据尽早读取到系统中来,这就引出了下面一点:
一般来说,大部分的反射构建对象元数据应该发生在系统配置阶段,比如在系统启动阶段,使用反射将系统运行所需要的相关配置及动态数据读进内存,然后在运行时,使用这些存放在内存中的元数据进行处理。
在最新的JVM中的hotspot优化,可以针对多次运行的Java Class进行有针对性的优化,因此理论上来说,Java代码执行的次数越多,则针对其的优化效果也越明显。
下面是一个有可能对代码有优化作用的实验,我并没有重复这个实验,你可以针对他的说法,进行针对性测试(http://www.cowtowncoder.com/blog/archives/2010/04/entry_396.html)
下面是一个号称提供 High performance java reflection library.的库。我也没有针对其做过测试。(https://code.google.com/p/reflectify-protocol/)
下面是一个用于支撑我上述概述第3点和第4点的一个用例
import java.lang.reflect.*;
class ReflectionOrNot {
public void run() {
try {
Thread.currentThread().sleep( 0 );
} catch( InterruptedException ie ){}
}
public static void main( String ... args ) throws Exception {
ReflectionOrNot ron = new ReflectionOrNot();
int max = 1000000;
long start = System.currentTimeMillis();
for( int i = 0 ; i < max ; i++ ) {
ron.run();
}
System.out.println( "Direct access took: " + ( System.currentTimeMillis() - start ) );
Method m = ReflectionOrNot.class.getDeclaredMethod("run");
start = System.currentTimeMillis();
for( int i = 0 ; i < max ; i++ ) {
m.invoke( ron );
}
System.out.println( "Reflection Took: " + ( System.currentTimeMillis() - start ) );
start = System.currentTimeMillis();
for( int i = 0 ; i < max ; i++ ) {
m = ReflectionOrNot.class.getDeclaredMethod("run");
m.invoke( ron );
}
System.out.println( "Lookup + Reflect : " + ( System.currentTimeMillis() - start ) );
}
}
下面是在我的机器上的执行结果
Direct access took: 247
Reflection Took: 588
Lookup + Reflect : 1394
Test 1 finished
Direct access took: 240
Reflection Took: 569
Lookup + Reflect : 1352
Test 2 finished
Direct access took: 244
Reflection Took: 574
Lookup + Reflect : 1383
Test 3 finished
Direct access took: 239
Reflection Took: 559
Lookup + Reflect : 1379
Test 4 finished
Direct access took: 227
Reflection Took: 575
Lookup + Reflect : 1383
Test 5 finished