Java 字节码中的 `obj.f(null)`

`obj.f(null)` in Java bytecode

假设 obj.f(null) 总是被编译为 2 连续 条指令是否安全

ACONST_NULL
INVOKEVIRTUAL <type-of-obj> f <descriptor-of-f>

by javac,无论 obj.f(null) 出现在源代码中的什么地方以及它如何与其他源代码混合?

编辑:我不打算进行可空性检查。我不关心 Object a = null; obj.f(a);.


编辑:@OliverCharlesworth 问了我原来的问题。我想用 asm 库检测字节码中的 obj.f(null) 。很容易想到2种方法来解决这个问题。

  1. 调用INVOKEVIRTUAL时,使用AnalyzerAdapter验证栈中最后一个元素是否为NULL类型。这当然有效,但涉及扩展堆栈帧,并且更昂贵。

  2. 检测到 ACONST_NULL,然后是 INVOKEVIRTUAL。它可能有效。但我不确定。因此,我在这里提出这个问题。

假设 obj.f 是一个非静态、非接口、非 superclass、非私有方法非 inner/outer class 方法(编辑:还有非可变参数),那么是的,我认为在实践中假设是安全的。当然,javac明天总是可以改变的,但是很难想象改变这个,因为这是编译相应代码的最简单和最自然的方式。

请注意,如果上面列出的任何条件成立,它的编译可能会有所不同。例如,静态方法显然会使用 invokestatic 而不是 invokevirtual。如果该方法是从内部 class 在外部 class 上调用的,它可能会改为调用编译器生成的合成方法,依此类推。