Java Operator Precedence example

412 views Asked by At

I know the Operator Precedence list, but I just cannot figure out what is the execution precedence in this code in "LINE 1". What Object is created before? For example: the My String or the new Precedence()? How can we apply the Operator Precedence rule in this example?

public class Precedence {
    public String s;
    public static void main (String ... args){
        String a = new Precedence().s="My String"; // LINE 1
        System.out.println(a);
    }
}

OUTPUT: My String

3

There are 3 answers

0
Sotirios Delimanolis On BEST ANSWER

This

String a = new Precedence().s="My String"; // LINE 1

is a local variable declaration statement with an initialization expression.

Every time it is executed, the declarators are processed in order from left to right. If a declarator has an initializer, the initializer is evaluated and its value is assigned to the variable.

a is the declarator. It's evaluated to produce a variable (itself). Then the initialization expression is evaluated.

This

new Precedence().s = "My String";

is an assignment expression. The left hand side of the operator is evaluated first to produce a variable, so new Precedence() is evaluated first, instantiates the class Precedence, producing a reference to an object. Then the right hand side of the assignment is evaluated, the String literal "My String", so a reference to a String object is produced. Then the assignment happens assigning the reference to the String object to the variable s of the object referenced by the value returned by the new instance creation expression.

Finally, since

At run time, the result of the assignment expression is the value of the variable after the assignment has occurred.

The value that was assigned to the field s of the Precedence object is also assigned to the variable a.

6
Robby Cornelissen On

Here's the bytecode:

public static transient varargs main([Ljava/lang/String;)V
   L0
    LINENUMBER 8 L0
    NEW Precedence
    DUP
    INVOKESPECIAL Precedence.<init> ()V
    LDC "My String"
    DUP_X1
    PUTFIELD Precedence.s : Ljava/lang/String;
    ASTORE 1

This shows the following execution order:

  1. Create Precedence object.
  2. Assign My String constant to Precedence.s.
  3. Assign it also to a.
2
Filip Bulovic On

There is tool javap, dissasembler, which will show you bytecode and from there you can conclude what is order of execution. It will output comments.

$ /usr/lib/jvm/java-7-oracle/bin/javap -c Precedence.class 
Compiled from "Precedence.java"
public class Precedence {
  public java.lang.String s;

  public Precedence();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return        

  public static void main(java.lang.String...);
    Code:
       0: new           #2                  // class Precedence
       3: dup           
       4: invokespecial #3                  // Method "<init>":()V
       7: ldc           #4                  // String My String
       9: dup_x1        
      10: putfield      #5                  // Field s:Ljava/lang/String;
      13: astore_1      
      14: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
      17: aload_1       
      18: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      21: return        
}

javap is part of JDK, path is on Linux, switch -c is Disassemble the code. Here is definition of instruction ldc, it is not obvious what it does

push a constant #index from a constant pool (String, int or float) onto the stack