首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >;或{}之间是否有细微差别来表示空语句?

问;或{}之间是否有细微差别来表示空语句?
EN

Stack Overflow用户
提问于 2013-11-25 19:51:20
回答 4查看 798关注 0票数 15

我知道语句结束符符号;,如果单独使用,则表示null语句。此外,“空循环体”可以是一种有用的编程构造,并且是使用null语句实现的。

查看下面的while语句,在第2行,我决定用一对背靠背的{}大括号替换终止的;符号。代码编译后运行正常。这是否意味着Java编译器用基于;的null语句替换了空代码块(由“空的”{}大括号表示)?

如果Java做了一些稍微不同的事情,那么在这两种情况下得到的字节码是否相同?很抱歉,我不能检查这台自动取款机。我是Java新手,还不具备显示和检查字节码的必要知识)。

代码语言:javascript
复制
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.
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-11-25 19:54:24

这两者在语义上是相同的,编译器将在这两种情况下生成相同的代码。如果您试图故意包含一个空的循环体,{}会更清楚地表明它是故意的,而不仅仅是一个零散的分号。您应该总是显式地注释这类情况,并且通常更好的做法是修改您的代码,以完全避免忙-等待循环。

票数 18
EN

Stack Overflow用户

发布于 2013-11-25 19:54:42

在这两种情况下都将生成相同的字节码。

我更喜欢使用{ }而不是;,后者在for和while循环中使用时有时会有输入错误的感觉。

如果我有这个代码:

代码语言:javascript
复制
while(i-- < j++);
System.out.println("Wild World");

我想也许是打字错误,;不应该出现在这里。

但如果我有:

代码语言:javascript
复制
while(i-- < j++) { }
System.out.println("Wild World");

我知道这是有原因的..

票数 16
EN

Stack Overflow用户

发布于 2013-11-25 20:13:59

作为一个好的衡量标准:

在其他两个答案的基础上,我将这两段代码放在一个示例中,如下所示:

代码语言:javascript
复制
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.
 }
}

和

代码语言:javascript
复制
 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,我得到了以下字节码:

代码语言:javascript
复制
    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
}

和

代码语言:javascript
复制
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
}

它们看起来是一样的,这意味着无论您选择哪种方式,编译器实现它的方式都是完全相同的。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20192363

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档