反射调用的性能和优化方案

对比

普通方法

    //普通方法
    public static void m1(){
        Cat cat = new Cat();

        long start = System.currentTimeMillis();

        for (int i = 0; i < 90000000; i++) {
            cat.say();
        }

        long end = System.currentTimeMillis();
        System.out.println("普通方法执行时间:"+(end-start));
    }

通过反射

//反射
    public static void m2() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        Class aClass = Class.forName("org.example.Cat");
        Object o = aClass.newInstance();
        Method say = aClass.getMethod("say");

        long start = System.currentTimeMillis();

        for (int i = 0; i < 90000000; i++) {
            say.invoke(o);
        }

        long end = System.currentTimeMillis();
        System.out.println("反射机制执行时间:"+(end-start));


    }

两者运行时间对比

普通方法执行时间:3 ms
反射机制执行时间:175 ms

优化

反射调用优化-关闭访问检查

  1. Method和 Field、 Constructor象都有 setAccessible()方法
  2. setAccessible()作用是启动和禁用访问安全检查的开关
    3.参数值为true表示反射的对象在使用时取消访向检查,提高反射的效率。
    参数值为 false则表示反射的对象执行访向检查

所以可以通过setAccessible()来优化反射。

其实呢,优化之后效率也没有高出很多。

    //反射优化
    public static void m3() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        Class aClass = Class.forName("org.example.Cat");
        Object o = aClass.newInstance();
        Method say = aClass.getMethod("say");

        //取消在反射调用方法时 取消访问检测
        say.setAccessible(true);


        long start = System.currentTimeMillis();

        for (int i = 0; i < 90000000; i++) {
            say.invoke(o);
        }

        long end = System.currentTimeMillis();
        System.out.println("反射优化机制执行时间:"+(end-start));

    }

执行结果对比

普通方法执行时间:3 ms
反射机制执行时间:176 ms
反射优化机制执行时间:129 ms