【问题标题】:Java do while, whileJava 做一会儿,一会儿
【发布时间】:2010-03-12 17:25:40
【问题描述】:

当我运行此代码时,我可以期待什么行为:

do while(testA) {

    // do stuff

} while(testB);

它的行为会像:

do {
    while(testA) {
        // do stuff
    }    
} while(testB);

或者:

if(testA) {
    do {
        // do stuff
    } while(testA && testB);
}

还是完全出乎意料?

我问这个问题是因为我认为这很模棱两可,对于搜索这个主题的其他人来说,不是因为我懒得测试它。

【问题讨论】:

  • 你应该期待的行为是同事用棍子打你。
  • @voyager 幸运的是,我没有需要注意的同事;不过感谢您的建议!

标签: java loops do-while ambiguity


【解决方案1】:

相当于你的第一个块:

do {
    while(testA) {
        // do stuff
    }    
} while(testB);

解析时Java grammar的相关部分是:

DoStatement:
    do Statement while ( Expression ) ;

Statement:
    WhileStatement

WhileStatement:
    while ( Expression ) Statement

Statement:
    Block

Block:
    { BlockStatements_opt }

您可以看到 Java 编译器会将其解析为 do <WhileStatement> while ( Expression ) ;。这是解析您编写的代码的唯一有效方法。

请记住,它没有任何特殊规则来解析此构造。由于 do-while 循环的编写方式不寻常,它最终只会让人类阅读感到困惑。在正常使用中,do-while 总是写成 do { ... } while 并带有显式花括号。

【讨论】:

    【解决方案2】:

    它确实有效,但行为取决于您正在测试的条件。例如。这段代码:

      int i = 2;
      int j = 4;
      do while(j > 0) {
           i--; j--;
           System.out.println("i:" + i + " j:" + j);
     } while(i > 0);
    

    输出:

    i:1 j:3
    i:0 j:2
    i:-1 j:1
    i:-2 j:0
    

    所以它的工作原理是:

    while(j>0) {
    
    }
    

    而通过交换变量名:

    do while(i > 0) {
        //.. same as above
     } while(j > 0);
    

    输出是:

    i:1 j:3
    i:0 j:2
    

    看起来它的行为与第一种情况相同(即考虑第一个时间),但在这里,应用程序没有终止!


    总结:
    testA 不再不满意 并且testB不满意 时,代码就像正常的while(testA){} 循环一样工作。
    但是:如果testA不再满足testB仍然满足,则循环不 不再执行,脚本没有终止。这仅适用于需要在循环内部更改“外部”循环的条件。

    更新: 在阅读其他答案后,我意识到这正是嵌套 do-while - while 循环的行为。
    无论如何,吸取的教训:不要使用这种语法,因为它会让你感到困惑;)

    【讨论】:

    • 它不会终止,因为一旦 i 达到 0,内部循环就不再运行——因此 j 永远无法达到 0。
    • 有趣,这显然是因为外部do while 循环会循环,但是do while 的内容不会循环,因为内部循环失败了一个条件!感谢您的测试。
    【解决方案3】:

    它的行为类似于

    do {
        while(testA) { 
            // stuff
        }
    } while(testB);
    

    所以,这段代码是这样解析的:

    在 testB 为真时执行 {a block of code}。其中 {a block of code} 是内部 while。

    这样写代码肯定有点不常见:)

    【讨论】:

      【解决方案4】:

      答案是#1。只要满足testB,它就会继续循环,但如果不满足testA,它就不会执行代码。

      【讨论】:

      • 这是合法的语法(JDK 1.6)。那么为什么它应该是非法代码呢?请解释一下。
      • 你说得对,我已经测试过了,答案是 #1。我已经编辑了我的答案。
      【解决方案5】:

      do {} while();”是一种构造,而“while(){}”是另一种构造。

      没有“do while”这样的东西;您无意中嵌套了它们并利用了 {} 对于单个指令是可选的这一事实。

      换句话说,这是合法的语法:

      do System.out.println("Hello World") while (true);
      

      if-statements 一样,块被视为单个语句。

      也就是说,您的第一个可能的答案是正确的,其中“while(){}”是外部“do {} while();”内的单个非括号内容

      【讨论】:

        【解决方案6】:

        我不认为这个代码是合法的。

        do while(testA) {
        
                // do stuff
        
            } while(testB);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-10-02
          • 2015-06-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多