使用嵌套赋值更新表达式中的引用

看一下类似这个问题的示例代码:

public class A { public static void main(String args[]){ A a = new A(); System.out.println(a.equals((a = null))); } } 

这打印错误。 为什么它不会因NullPointerException而失败? 在equals方法可以运行之前必须处理赋值,但是在评估整行之前,不会以某种方式影响equals的引用?

我没有看到它描述的Java语言规范在哪里,我在某个地方想念它吗?

来自JLS :

在运行时,方法调用需要五个步骤。 首先,可以计算目标参考。 其次,评估参数表达式。 第三,检查要调用的方法的可访问性。 第四,找到要执行的方法的实际代码。 第五,创建新的激活帧,如果需要则执行同步,并且将控制转移到方法代码。

这表明在a.equals((a = null)) 。 发生以下步骤:

  1. a的参考值被计算出来。 这有时称为“绑定方法调用”。
  2. a=null被评估为评估参数的一部分。 它不会影响第1步。
  3. 检查equals(Object)的可访问性。
  4. JVM内部代码查找实际的字节码。
  5. 发生调用

显然,a的引用是 a被清零之前确定的,从而避免了NPE。

我相信您感兴趣的JLS部分是

15.12.4。 方法调用的运行时评估

在运行时,方法调用需要五个步骤。 首先,可以计算目标参考。 其次,评估参数表达式

因此,在仍具有非空值的情况下发生目标的评估,然后将a设置为null作为方法调用的参数。 因此,调用equals方法时引用以前称为a的对象,该对象仍然存在,带有null参数。