6 System.out.println(Thread.currentThread().getStackTrace()[1].getClassName());
7 System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName());
8 System.out.println(Thread.currentThread().getStackTrace()[1].getLineNumber());
9
10 }
11 /* 输出结果如下:
12 main
13 MyTest.java
14 MyTest
15 main
16 12
17 */
7. 基于反射的方法调用和普通的方法调用之间的效率差别:
我们在本篇开始的部分已经提到反射确实可以给我们的程序带来极大的灵活性,目前很多流行的框架都是非常依赖于Java提供的反射机制,反射几乎处处可见。然而这并不能成为我们滥用他的理由,还是那句话,没有免费的午餐,反射的灵活性是用极大的效率牺牲换来的,见下例:
1 public class MyTest {
2 public static void main(String args[]) throws Exception {
3 try {
4 final int CALL_AMOUNT = 1000000;
5 final MyTest ri = new MyTest();
6 int idx = 0;
7 //1. 直接使用正常的方法调用(没有反射)
8 long millis = System.currentTimeMillis();
9 for (idx = 0; idx < CALL_AMOUNT; ++idx)
10 ri.getValue();
11 System.out.println("Calling method " + CALL_AMOUNT
12 + " times programatically took "
13 + (System.currentTimeMillis() - millis) + " millis");
14
15 //2. 通过反射调用域方法,而且每次都重新获取该域方法的反射类。
16 millis = System.currentTimeMillis();
17 for (idx = 0; idx < CALL_AMOUNT; idx++) {
18 Method md = ri.getClass().getMethod("getValue", null);
19 md.invoke(ri, null);
20 }
21 System.out.println("Calling method " + CALL_AMOUNT
22 + " times reflexively with lookup took "
23 + (System.currentTimeMillis() - millis) + " millis");
24
25 //3.通过反射调用域方法,但是该方法的反射对象并不是每次都
26 //重新获取,而是重复使用,只是在域方法调用的时候通过反射完成。
27 Method md = ri.getClass().getMethod("getValue", null);
28 millis = System.currentTimeMillis();
29 for (idx = 0; idx < CALL_AMOUNT; idx++)
30 md.invoke(ri, null);
31 System.out.println("Calling method " + CALL_AMOUNT
32 + " times reflexively with cache took "
33 + (System.currentTimeMillis() - millis) + " millis");
34 } catch (final NoSuchMethodException ex) {
35 throw new RuntimeException(ex);
36 } catch (final InvocationTargetException ex) {
37 throw new RuntimeException(ex);
38 } catch (final IllegalAccessException ex) {
39 throw new RuntimeException(ex);
40 }
41 }
42 public String getValue() {
43 return this.value;
44 }
45 private String value = "some value";
46 }
47 /* 输出结果如下:www.2cto.com
48 Calling method 1000000 times programatically took 0 millis
49 Calling method 1000000 times reflexively with lookup took 1422 millis
50 Calling method 1000000 times reflexively with cache took 110 millis
51 */