Java 运算符优先级示例
Java Operator Precedence example
我知道Operator Precedence list,但我无法弄清楚“LINE 1”中这段代码的执行优先级是多少。之前创建了什么对象?例如:My String
还是 new Precedence()
?我们如何在此示例中应用运算符优先级规则?
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);
}
}
输出:
My String
这是字节码:
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
这显示了以下执行顺序:
- 创建
Precedence
对象。
- 将
My String
常量分配给 Precedence.s
。
- 也将其分配给
a
。
这个
String a = new Precedence().s="My String"; // LINE 1
是一个带有初始化表达式的local variable declaration statement。
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
是声明符。它被评估为产生一个变量(本身)。然后计算初始化表达式。
这个
new Precedence().s = "My String";
是an assignment expression。首先计算运算符的左侧以生成变量,因此首先计算 new Precedence()
,实例化 class Precedence
,生成对对象的引用。然后评估赋值的右侧,即 String
文字 "My String"
,因此会生成对 String
对象的引用。然后赋值发生,将对 String
对象的引用赋给新实例创建表达式返回的值引用的对象的变量 s
。
最后,由于
At run time, the result of the assignment expression is the value of
the variable after the assignment has occurred.
分配给 Precedence
对象的字段 s
的值也分配给变量 a
.
有工具javap, dissassembler,它会向你展示字节码,从那里你可以得出什么是执行顺序。它会输出评论。
$ /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 是 JDK 的一部分,路径在 Linux 上,开关 -c 是反汇编代码。这是指令 ldc 的定义,它的作用并不明显
push a constant #index from a constant pool (String, int or float) onto the stack
我知道Operator Precedence list,但我无法弄清楚“LINE 1”中这段代码的执行优先级是多少。之前创建了什么对象?例如:My String
还是 new Precedence()
?我们如何在此示例中应用运算符优先级规则?
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);
}
}
输出:
My String
这是字节码:
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
这显示了以下执行顺序:
- 创建
Precedence
对象。 - 将
My String
常量分配给Precedence.s
。 - 也将其分配给
a
。
这个
String a = new Precedence().s="My String"; // LINE 1
是一个带有初始化表达式的local variable declaration statement。
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
是声明符。它被评估为产生一个变量(本身)。然后计算初始化表达式。
这个
new Precedence().s = "My String";
是an assignment expression。首先计算运算符的左侧以生成变量,因此首先计算 new Precedence()
,实例化 class Precedence
,生成对对象的引用。然后评估赋值的右侧,即 String
文字 "My String"
,因此会生成对 String
对象的引用。然后赋值发生,将对 String
对象的引用赋给新实例创建表达式返回的值引用的对象的变量 s
。
最后,由于
At run time, the result of the assignment expression is the value of the variable after the assignment has occurred.
分配给 Precedence
对象的字段 s
的值也分配给变量 a
.
有工具javap, dissassembler,它会向你展示字节码,从那里你可以得出什么是执行顺序。它会输出评论。
$ /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 是 JDK 的一部分,路径在 Linux 上,开关 -c 是反汇编代码。这是指令 ldc 的定义,它的作用并不明显
push a constant #index from a constant pool (String, int or float) onto the stack