java反射为什么比较慢?reflect的性能开销:
- 变长方法参数导致导致的Object数组
- 基本类型自动装箱拆箱
- 最后就是方法内连
反射的调用采用委派方式,目的是在本地调用和动态实现之间切换
本地调用,15次之后转成动态实现,动态实现的字节码是动态生成的
- 本地调用, 本地调用会经过java - c++ -java的实现,比动态实现慢一些
- 动态实现, 动态实现会生成字节码,生成字节码非常耗时,所以如果调用量不大的时候使用本地调用比较好。
public class Test {
public static void target(int i) {
new Exception("#" + i).printStackTrace();
}
public static void main(String[] args) throws Exception{
Class> aClass = Class.forName("com.baeldung.java.reflection.Test");
Method target = aClass.getMethod("target", int.class);
for (int i = 0; i < 20; i++) {
target.invoke(null, i);
}
}
}
看一下实现效果
- 上述打印的异常栈可以看出:
- sun.reflect.DelegatingMethodAccessorImpl 所有的反射都是这个方法出发,也就是委托实现,使用它是为了方便本地方法和动态实现的方法互相切换
- sun.reflect.NativeMethodAccessorImpl 开始前面0-15次都是使用的本地方法调用
- 第16次开始, sun.reflect.GeneratedMethodAccessor1.invoke 直接使用具体实现的字节码
- 第16次开销最大,因为需要生成字节码