Java Operator Precedence Example
I know the Operator Priority List , but I just can't figure out what the execution priority is in this code in "LINE 1". What object was created earlier? For example: My String
or 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
source to share
it
String a = new Precedence().s="My String"; // LINE 1
is a local variable declaration directive with an initialization expression.
Each time it is executed, declarators are processed in order from left to right. If the declarator has an initializer, the initializer and its value are assigned to the variable.
a
is a declarator. He appreciated creating a variable (itself). The initialization expression is then evaluated.
it
new Precedence().s = "My String";
assignment expression . The left side of the operator is evaluated first to create a variable, so it is evaluated first new Precedence()
, instantiates the class Precedence
by creating an object reference. Then the right side of the assignment, String
literal "My String"
, is evaluated , so an object reference is created String
. The assignment then assigns the reference to the object String
variable of the s
object referenced by the value returned by the create new instance expression.
Finally, since
At run time, the result of the assignment expression is the value of the variable after assignment.
The value assigned to the s
object field Precedence
is also assigned to the variable a
.
source to share
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
The order of execution is shown here:
- Create object
Precedence
. - Assign a
My String
constantPrecedence.s
. - Assign it as well
a
.
source to share
There is a javap tool, dissasembler that will show you the bytecode and from there you can infer what the execution order is. It will display 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 in Linux, switch -c is to disassemble code. Here is the definition of ldc command, it is not obvious what it does
push a constant #index from a constant pool (String, int or float) onto the stack
source to share