反射的基本使用方式

一.反射基本介绍

1.1反射为什么慢

编译器无法优化反射相关的代码,所以导致反射较慢;
stack_flow

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.

因为反射是动态调用类型(type),所以jvm优化器无法对其进行优化。因此反射操作拖慢了性能,我盟应该避免在频繁操作且性能敏感的区域使用反射。

如一下简单内部类A,使用两种方式创建三百万次实例并放进数组中,性能差异较大前者43 ns,后者217 ns

测试代码:


package reflect;

/**
 * @author 杜艮魁
 * @date 2018/1/25
 */
public class Run {
    private static final int RUNS = 3000000;

    public static class A {
    }

    public static void main(String[] args) throws Exception {
        doRegular();
        doReflection();
        doRegular();
        doReflection();//这里貌似给优化了
    }

    public static void doRegular() throws Exception {
        A[] as = new A[RUNS];
        long start = System.nanoTime();
        for (int i = 0; i < RUNS; i++) {
            as[i] = new A();
        }
        System.out.printf("new A(), %,d ns%n", (System.nanoTime() - start)/RUNS);
    }

    public static void doReflection() throws Exception {
        A[] as = new A[RUNS];
        long start = System.nanoTime();
        for (int i = 0; i < RUNS; i++) {
            as[i] = A.class.newInstance();
        }
        System.out.printf("A.class.newInstance(), %,d ns%n", (System.nanoTime() - start)/RUNS);
    }
}

1.2通过反射获取对象

获取“无参构造函数”对象和“有参构造函数”对象

//抽象类和接口都无法实例化;
Class clz=Class.forName("reflect.Ele");
//返回一个无参实例,而且Class的newInstance()方法只有无参的
Ele instrument=(Ele)clz.newInstance();

//有构造参数有参类对象使用反射创建对象的方式
Class clzX=Class.forName("reflect.Handler");
Constructor cons=clzX.getConstructor(int.class);//此方法参数为可变参数,写的是构造函数的参数Class类
Handler objWithParam=(Handler)cons.newInstance(1);
System.out.println(objWithParam.num);

posted on 2018-04-21 13:45  coderDu  阅读(510)  评论(0)    收藏  举报