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种方法来解决这个问题。
调用INVOKEVIRTUAL
时,使用AnalyzerAdapter
验证栈中最后一个元素是否为NULL
类型。这当然有效,但涉及扩展堆栈帧,并且更昂贵。
检测到 ACONST_NULL
,然后是 INVOKEVIRTUAL
。它可能有效。但我不确定。因此,我在这里提出这个问题。
假设 obj.f
是一个非静态、非接口、非 superclass、非私有方法非 inner/outer class 方法(编辑:还有非可变参数),那么是的,我认为在实践中假设是安全的。当然,javac
明天总是可以改变的,但是很难想象改变这个,因为这是编译相应代码的最简单和最自然的方式。
请注意,如果上面列出的任何条件成立,它的编译可能会有所不同。例如,静态方法显然会使用 invokestatic
而不是 invokevirtual
。如果该方法是从内部 class 在外部 class 上调用的,它可能会改为调用编译器生成的合成方法,依此类推。
假设 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种方法来解决这个问题。
调用
INVOKEVIRTUAL
时,使用AnalyzerAdapter
验证栈中最后一个元素是否为NULL
类型。这当然有效,但涉及扩展堆栈帧,并且更昂贵。检测到
ACONST_NULL
,然后是INVOKEVIRTUAL
。它可能有效。但我不确定。因此,我在这里提出这个问题。
假设 obj.f
是一个非静态、非接口、非 superclass、非私有方法非 inner/outer class 方法(编辑:还有非可变参数),那么是的,我认为在实践中假设是安全的。当然,javac
明天总是可以改变的,但是很难想象改变这个,因为这是编译相应代码的最简单和最自然的方式。
请注意,如果上面列出的任何条件成立,它的编译可能会有所不同。例如,静态方法显然会使用 invokestatic
而不是 invokevirtual
。如果该方法是从内部 class 在外部 class 上调用的,它可能会改为调用编译器生成的合成方法,依此类推。