使用嵌套赋值更新表达式中的引用
看一下类似这个问题的示例代码:
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))
。 发生以下步骤:
-
a
的参考值被计算出来。 这有时称为“绑定方法调用”。 -
a=null
被评估为评估参数的一部分。 它不会影响第1步。 - 检查
equals(Object)
的可访问性。 - JVM内部代码查找实际的字节码。
- 发生调用
显然,a的引用是在 a
被清零之前确定的,从而避免了NPE。
我相信您感兴趣的JLS部分是
15.12.4。 方法调用的运行时评估
在运行时,方法调用需要五个步骤。 首先,可以计算目标参考。 其次,评估参数表达式
因此,在仍具有非空值的情况下发生目标的评估,然后将a
设置为null
作为方法调用的参数。 因此,调用equals方法时引用以前称为a
的对象,该对象仍然存在,带有null参数。
- 多个套接字导致ConnectException:连接被拒绝:连接
- 对List 进行排序
- Methods.class中的代码重用与策略模式和dependency injection
- 在Set toArray()方法中需要新的String
- java.lang.SecurityException:类“org.apache.log4j.Logger”与同一包中其他类的信任级别不匹配
- 我怎么能在一个线程中停止块方法DatagramSocket.receive()
- Java – Scanner – 跳过我上次的nextLine()请求
- ClassNotFoundException:org.eclipse.xtext.junit_2.4.3.v201309030823找不到junit.framework.TestCase
- Spring JTA TransactionManager config:支持Tomcat和JBoss