今天突然想到Java反射。然后测试了一下1.8.0_191版本的反射性能,没想到反射竟然比直接调用性能还高。
反射介绍
java为什么要用反射。Java反射是指在程序运行状态中,能检查任意对象的内容并调用任意方法。对于任何一个对象,我们都能够对它的方法和属性进行调用。我们把这种动态获取对象信息和调用对象方法的功能称之为反射机制。
测试代码
反射调用的类
public class ClassA {
private String name;
public void setName(String name) {
this.name = name;
}
}
测试主类
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Method;
@Slf4j
public class MapMain {
private static final int COUNT = 100000;
public static void main(String[] args) {
System.out.println("starting ...");
long start = System.currentTimeMillis();
for (int i = 0; i < COUNT; i++) {
ClassA clzA = new ClassA();
clzA.setName("A" + i);
}
long end = System.currentTimeMillis();
long diff = end - start;
System.out.println("native call:" + diff);
try {
long start2 = System.currentTimeMillis();
for (int i = 0; i < COUNT; i++) {
Class clzA = Class.forName("com.yq.myreflect.ClassA");
Class>[] argsType = new Class[1];
argsType[0] = String.class;
Method m = clzA.getMethod("setName", argsType);
Object obj = clzA.newInstance();
m.invoke(obj, "A" + i);
}
long end2 = System.currentTimeMillis();
long diff2 = end2 - start2;
System.out.println("reflect call:" + diff2);
} catch (Exception ex) {
ex.printStackTrace();
}
try {
long start3 = System.currentTimeMillis();
//缓存类,避免多次查找
Class clzA = Class.forName("com.yq.myreflect.ClassA");
Class>[] argsType = new Class[1];
argsType[0] = String.class;
//缓存方法,避免多次查找
Method m = clzA.getMethod("setName", argsType);
for (int i = 0; i < COUNT; i++) {
Object obj = clzA.newInstance();
m.invoke(obj, "A" + i);
}
long end3 = System.currentTimeMillis();
long diff3 = end3 - start3;
System.out.println("cache call:" + diff3);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
测试结果
多次运行的平均结果
starting ...
native call:33
reflect call:126
cache call:16
结果分析
可以看到如果我们缓存了类,以及要调用的方法后,使用反射比直接调用还快。
//缓存类,避免多次查找
Class clzA = Class.forName("com.yq.myreflect.ClassA");
Class>[] argsType = new Class[1];
argsType[0] = String.class;
//缓存方法,避免多次查找
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态