我知道语句结束符符号;,如果单独使用,则表示null语句。此外,“空循环体”可以是一种有用的编程构造,并且是使用null语句实现的。
查看下面的while语句,在第2行,我决定用一对背靠背的{}大括号替换终止的;符号。代码编译后运行正常。这是否意味着Java编译器用基于;的null语句替换了空代码块(由“空的”{}大括号表示)?
如果Java做了一些稍微不同的事情,那么在这两种情况下得到的字节码是否相同?很抱歉,我不能检查这台自动取款机。我是Java新手,还不具备显示和检查字节码的必要知识)。
int i=0,j=100;
// Either a terminating ; symbol or {} braces work to make an "empty loop body".
while (++i < --j) {}
System.out.println("The midpoint between 0 and 100 is " +i); // Midpoint is 50.发布于 2013-11-25 19:54:24
这两者在语义上是相同的,编译器将在这两种情况下生成相同的代码。如果您试图故意包含一个空的循环体,{}会更清楚地表明它是故意的,而不仅仅是一个零散的分号。您应该总是显式地注释这类情况,并且通常更好的做法是修改您的代码,以完全避免忙-等待循环。
发布于 2013-11-25 19:54:42
在这两种情况下都将生成相同的字节码。
我更喜欢使用{ }而不是;,后者在for和while循环中使用时有时会有输入错误的感觉。
如果我有这个代码:
while(i-- < j++);
System.out.println("Wild World");我想也许是打字错误,;不应该出现在这里。
但如果我有:
while(i-- < j++) { }
System.out.println("Wild World");我知道这是有原因的..
发布于 2013-11-25 20:13:59
作为一个好的衡量标准:
在其他两个答案的基础上,我将这两段代码放在一个示例中,如下所示:
public class SO {
public static void main(String[] args){
int i=0,j=100;
// Either a terminating ; symbol or {} braces work to make an "empty loop body".
while (++i < --j) {}
System.out.println("The midpoint between 0 and 100 is " +i); // Midpoint is 50.
}
}和
public class SO2 {
public static void main(String[] args){
int i=0,j=100;
// Either a terminating ; symbol or {} braces work to make an "empty loop body".
while (++i < --j) ;
System.out.println("The midpoint between 0 and 100 is " +i); // Midpoint is 50.
}
}使用javap -c,我得到了以下字节码:
Compiled from "SO.java"
public class SO {
public SO();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: bipush 100
4: istore_2
5: iinc 1, 1
8: iload_1
9: iinc 2, -1
12: iload_2
13: if_icmpge 19
16: goto 5
19: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
22: new #3 // class java/lang/StringBuilder
25: dup
26: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
29: ldc #5 // String The midpoint between 0 and 100 is
31: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
34: iload_1
35: invokevirtual #7 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
38: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
41: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
44: return
}和
Compiled from "SO2.java"
public class SO2 {
public SO2();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: bipush 100
4: istore_2
5: iinc 1, 1
8: iload_1
9: iinc 2, -1
12: iload_2
13: if_icmpge 19
16: goto 5
19: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
22: new #3 // class java/lang/StringBuilder
25: dup
26: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
29: ldc #5 // String The midpoint between 0 and 100 is
31: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
34: iload_1
35: invokevirtual #7 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
38: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
41: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
44: return
}它们看起来是一样的,这意味着无论您选择哪种方式,编译器实现它的方式都是完全相同的。
https://stackoverflow.com/questions/20192363
复制相似问题