要么使用字节码分析,要么使用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