java反射实现

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);
        }


    }
}

看一下实现效果


java反射实现_第1张图片
image.png

java反射实现_第2张图片
image.png
  • 上述打印的异常栈可以看出:
  • sun.reflect.DelegatingMethodAccessorImpl 所有的反射都是这个方法出发,也就是委托实现,使用它是为了方便本地方法和动态实现的方法互相切换
  • sun.reflect.NativeMethodAccessorImpl 开始前面0-15次都是使用的本地方法调用
  • 第16次开始, sun.reflect.GeneratedMethodAccessor1.invoke 直接使用具体实现的字节码
  • 第16次开销最大,因为需要生成字节码

你可能感兴趣的:(java反射实现)