Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

updating references in an expression with a nested assignment

Looking at this example code similar to this question:

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

This prints false. Why doesn't it fail with a NullPointerException? The assignment has to get processed before the equals method can run, but somehow that doesn't affect the reference that equals is called on until after the whole line is evaluated?

I didn't see where in the Java language spec it describes this, did I miss it somewhere?

like image 396
Nathan Hughes Avatar asked May 23 '14 18:05

Nathan Hughes


1 Answers

From JLS:

At run time, method invocation requires five steps. First, a target reference may be computed. Second, the argument expressions are evaluated. Third, the accessibility of the method to be invoked is checked. Fourth, the actual code for the method to be executed is located. Fifth, a new activation frame is created, synchronization is performed if necessary, and control is transferred to the method code.

This shows that in a.equals((a = null)). the following steps occur:

  1. a's reference is computed. This is sometimes called "binding the method call".
  2. a=null is evaluated as part of evaluating arguments. It does not affect step 1.
  3. The accessibility of equals(Object) is checked.
  4. JVM internal code finds the actual bytecode.
  5. Invocation occurs

Clearly, the reference of a is determined before a is nulled, averting an NPE.

like image 191
nanofarad Avatar answered Sep 28 '22 08:09

nanofarad