要麼使用字節碼分析,要麼使用System.nanoTime
這兩種方法計時。我認爲第二個更快。這裏是我做過什麼來結束這:
我寫了三個類,如下所示:
public static class A {
public B b = new B();
}
public static class B {
public E e = new E();
}
public static class E {
public String name = "s";
public int age = 1;
}
然後我寫了兩個簡單的方法,並使用javap -c CLASS_NAME
得到他們的Java字節碼。
public static void Test1() {
A a = new A();
String str = a.b.e.name;
int age = a.b.e.age;
}
上述方法的字節碼是:
public static void Test1();
Code:
// new A();
0: new #15
3: dup
4: invokespecial #17
7: astore_0
8: aload_0
// a.b (it accesses the field and put it on operand stack)
9: getfield #18
// b.e
12: getfield #22
// b.name
15: getfield #28
// pop 'name' from stack
18: astore_1
19: aload_0
// cyle continues
20: getfield #18
23: getfield #22
26: getfield #34
29: istore_2
30: return
您可以在字節代碼級清楚地看到,在每次嘗試訪問現場時,它就把這個值上堆申請,然後這個循環繼續。因此,a.a1.a2....an
將是n
指令,如果堆棧將有足夠的空間來容納所有n
。並且編譯器沒有優化再次調用同一個週期來訪問name
和age
字段。
現在這裏是第二種方法:對上述方法
public static void Test2() {
A a = new A();
E e = a.b.e;
String str = e.name;
int age = e.age;
}
字節代碼是:
public static void Test2();
Code:
// new A();
0: new #15
3: dup
4: invokespecial #17
7: astore_0
8: aload_0
// store a.b.e on operand stack once
9: getfield #18
12: getfield #22
15: astore_1
16: aload_1
// get 'name' field
17: getfield #28
20: astore_2
21: aload_1
// get 'age' field
22: getfield #34
25: istore_3
26: return
以上是4個指令比以前更短的代碼,因爲它防止了getfield
執行。所以我認爲這應該比以前更快。
你正在尋找的詞是'鏈接'獲取。嵌套意味着一個獲得正在另一個環境中發生。 – Perception