我假设lifeTime是在声明时分配的最终字段:
final int lifeTime = 0x0001;
如果是这样,则按以下方式优化字节码(它与VM几乎没有关系,纯编译器不可思议):
- 无需真正从内存中获取数据:所需要做的只是加载常量1。
- 但是,如果该字段的所有者恰好为 空,该 怎么办?在这种情况下,必须抛出NullPointerException。为了保证这种行为,编译器发出对getClass()的调用,因为
- 实际检查是否为空,构造一个新的NullPointerException实例并将其抛出是 很多 字节代码,
- 这样的调用在VM中进行了非常优化,
- 此方法始终可用,
- 它不需要任何参数。
一个简单的例子:
class Test { private final int myFinalField = 1; int test(Test t) { return t.myFinalField; }}如果我们看一下test()方法的字节码(这次是JVM,但是如果您将其转换为Dalvik,则本质上是相同的),这也是对getClass()的调用:
// access flags 0x0 test(LTest;)I L0 LINENUMBER 5 L0 // load t ALOAD 1 // if (t == null) throw new NullPointerException(); compressed in only two instructions INVOKEVIRTUAL java/lang/Object.getClass ()Ljava/lang/Class; POP // the actual value of myFinalField ICONST_1 IRETURN L1 LOCALVARIABLE this LTest; L0 L1 0 LOCALVARIABLE t LTest; L0 L1 1 MAXSTACK = 1 MAXLOCALS = 2



