当您通过this 引用访问own 实例字段时(例如,object
或int
来自私有(private)方法的字段),生成的 Android Dalvik 字节码将包含一个 iget
字节码指令:
iget v2, p0, Lcom/example/myapp/MyClass;->status:I
这与您访问另一个对象的字段时发出的指令相同(即不是通过 this
指针),因此它似乎无法区分其他对象和您自己。在字节码中,这是可以理解的,但 JIT 可以做得更多。
检查 Android 源代码,我没有看到 JIT 在这种情况下(即当您访问 this
时)会自动消除 null 检查。它在已经空检查的 Dalvik 寄存器的基本 block 中被消除,很好,但是(对我来说)它似乎也可以被 this
访问消除(即使它是基本的第一条指令 block 或任何指令,因为 this
不能为空)。
我错过了什么?是出于安全/运行时类型安全的原因吗?或者我只是忽略了源代码?为什么 VM (JIT) 不能以不同的方式处理 this
? (我明白 native 代码显然不能,因为 this
是一个内存地址,就像其他任何东西一样。)
编辑:据我所知,每次基本 block 在 dvm 中结束时,都会清除“已空检查”标志。我要说的是,保存 this 的寄存器的“已空检查”标志可以预先设置为 1(即使在基本之间的转换期间也不需要清除该值 block )。
最佳答案
从字节码的角度来看,访问“this”对象上的字段与访问任何其他对象上的字段没有什么不同——您仍然必须传入一个包含“this”引用的寄存器。由于无法保证传入的寄存器实际上包含非空值,因此它仍然必须执行 nullness 检查,就像对任何其他对象一样。
关于java - 为 'this' 访问发出空检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16115251/