java反射很慢吗?import java.lang.reflect.InvocationTargetExceptionimport java.lang.reflect.Methodi
java反射很慢吗?
import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import org.apache.commons.lang.time.StopWatch;/* * @Description * * @CreateDate 2011-9-15 * * @Author <a href="mailto:bohr.qiu@gmail.com">Bohr.Qiu</a> */public class PerformaceTest {public int test() {int sum = 0;for (int i = 0; i < 10000; i++) {sum += i;}return sum;}public Method test1(){PerformaceTest test1 = new PerformaceTest();Method method=null;try {for (int i = 0; i < 10000; i++) { method = test1.getClass().getDeclaredMethod("test");}} catch (SecurityException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();}return method;}/** * @param args * @throws NoSuchMethodException * @throws SecurityException * @throws InvocationTargetException * @throws IllegalAccessException * @throws IllegalArgumentException */public static void main(String[] args) throws SecurityException,NoSuchMethodException, IllegalArgumentException,IllegalAccessException, InvocationTargetException {PerformaceTest test = new PerformaceTest();StopWatch sw = new StopWatch();sw.start();int times = 500000;//测试直接调用for (int i = 0; i < times; i++) {test.test();}sw.stop();System.out.println("direct:" + sw.toString());Method method = test.getClass().getDeclaredMethod("test");sw.reset();sw.start();//测试反射调用for (int i = 0; i < times; i++) {method.invoke(test);}sw.stop();System.out.println("reflect:" + sw.toString());sw.reset();sw.start();//测试直接调用for (int i = 0; i < times; i++) {test.test();}sw.stop();System.out.println("direct" + sw.toString());sw.reset();sw.start();//测试反射调用for (int i = 0; i < times; i++) {method.invoke(test);}sw.stop();System.out.println("reflect:" + sw.toString());sw.reset();sw.start();times=times/1000;//测试反射类探测,测试测试减少为1000倍for (int i = 0; i < times; i++) {test.test1();}sw.stop();System.out.println("getreflect:" + sw.toString());}}为了减少环境因素的影响,多次测试结果如下:
第一次输出:
direct:0:00:05.516
reflect:0:00:05.531
direct0:00:06.360
reflect:0:00:05.515
getreflect:0:00:06.453
第二次输出:
direct:0:00:05.578
reflect:0:00:05.562
direct0:00:06.391
reflect:0:00:05.547
getreflect:0:00:06.484
可以看出,反射对象探测,确实很慢,差距很大。但是仅仅是反射调用呢,和直接调用比较,没有任何差别,甚至出现反射调用比直接调用更快的情况。
如果我们能缓存住Method对象,我们不需要担心性能了。
当然,如果反射抛出了异常,SecurityException,
NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException
增加了异常栈的开销,不过这样的异常我们是可以屏蔽的,程序的调用逻辑我们控制好了,就不用担心这样的现象。
