【问题标题】:Scope of do-while loop?do-while循环的范围?
【发布时间】:2011-12-25 12:15:59
【问题描述】:

在 Java 中,do-while 循环的主体和循环条件不属于同一范围。所以下面的代码不会编译:

do {
    boolean b = false;
} while (b); // b cannot be resolved to a variable

但这段代码对我来说确实有意义。

另外,如果正文和条件在同一范围内,我找不到任何陷阱;因为body总是会被执行,而Java没有Goto,我不知道如何跳过最外层do-while body范围内的变量声明。即使有可能,编译器总能检测到这种可能性,然后产生编译时错误。

这种行为是否有任何原因(除了将do-while 循环保持与while 相同的格式)?我真的很好奇。感谢您的任何意见!

【问题讨论】:

  • 我认为这是因为 Java 中的作用域按块 {}.
  • Java 中的作用域由大括号清楚地描述。请注意,while(b) 在花括号之外,而布尔值 b 在里面。这将它们置于不同的范围内。
  • 你能像在 C/C++ 中那样在 Java 中使用无关的 {} 吗?
  • (虽然我要补充一点,如果你使用额外的{} 来创建块,你可能做错了,应该重构。)

标签: java scope


【解决方案1】:

按照您的逻辑,b 在首次使用之前不会被定义:

do {
    continue;
    boolean b = false;
} while (b); // b cannot be resolved to a variable

请注意,boolean 标志通常是一种代码异味,尽量避免使用它们而不是与之抗争。

【讨论】:

  • 我怀疑这是否是真正的问题?如果这是一个while循环,那么编译器会抱怨“无法访问的代码”,但由于这是一个do-while循环,编译器只会抱怨没有声明b,但我想如果do-while编译器也会做同样的事情是一个单一的范围。谢谢!
  • 嗯,真正的问题是变量的范围仅限于声明它的{} 块。时期。我只是想告诉你,即使不是这种情况,也可以在不定义b 的情况下达到while 条件。
  • 如果存在if 语句并且continue 在then 部分中,则编译器无法给出关于“无法访问的代码”的警告。
  • 我只是讨厌在没有解释的情况下收到反对票。如果我错了请纠正我,我也想在这里学习一些东西:-)。
  • 我喜欢这个例子;为我 +1。
【解决方案2】:

因为这是 Java 定义范围的一种方式; {} 内部是一个新作用域。

IMO 对单个构造进行特殊处理没有多大意义。

【讨论】:

  • 那么除了一般规则之外没有真正的问题吗?我现在需要查看规范:)
  • @ZiyaoWei 没问题,只是和你想的不一样:)
  • Java 并不总是使用 {} 定义范围。例如,代码“for (int z=0;z
  • @AdamGawne-Cain 这不会改变 {} 内部的一个新范围,特定于 OP 的问题。这就是说:for 循环变量的范围是作为块内的局部变量声明显式执行的;这些 var decls 的范围与在块中声明的范围完全相同。 (而且必须是,因为 for 循环的语句可能不是块语句)。但我会调整措辞。
【解决方案3】:

在您的示例中,布尔变量 b 的范围为 do..while 循环的主体。由于条件检查是在主体外部执行的,因此变量超出了范围。正确的结构是:

boolean b = false ; // Or whichever initial value you want
do {
    b = false;
} while (b);

【讨论】:

    【解决方案4】:

    如果你想退出 do-while 块,而 boolean 定义在 do-while 块内,你可以写这样的东西。

    do{
      boolean b;
      ...
      if(b){
        break;
      }
    }while(otherCondition)  //or while(true)
    

    【讨论】:

      【解决方案5】:
      do {
          boolean b = false;
      }
      while (b);
      

      因为布尔变量b 是一个局部变量,其范围仅在block 内。

      来自JLS

      每个局部变量声明语句都立即包含在 一个块。

      【讨论】:

        【解决方案6】:

        这是基本的范围规则。在一组花括号 {} 中声明的变量在花括号末尾超出范围。它违反了标准范围规则,编译器检测这种情况将是额外的工作。

        【讨论】:

          【解决方案7】:

          语句定义和变量在语句块{} 之外不可见,这就是编译器抱怨的原因。

          whiledo ... while 的区别在于do ... while 保证至少执行一次,这是根据JLS 编写的更简单的方式

          关于变量的范围,它必须是可见的,根据these rules 否则你会得到一个编译时错误。

          【讨论】:

            【解决方案8】:
            public class DoWhileLoopExample {
            
                public static void main(String[] args) {
            
                    int i=1;
                    do {
                        System.out.println("Do While Loop Example");
            
                    } while(i<1);
                }
            }
            

            【讨论】:

            猜你喜欢
            • 2016-01-24
            • 1970-01-01
            • 2021-11-20
            • 2018-05-09
            • 2015-07-03
            • 2016-02-21
            • 2013-03-24
            • 2020-11-26
            • 1970-01-01
            相关资源
            最近更新 更多