【问题标题】:Why enhanced for loop does not fail when ends with semicolon?为什么以分号结尾时增强的for循环不会失败?
【发布时间】:2016-05-22 05:02:17
【问题描述】:

我正在学习 Java 认证,在一次模拟考试中,我看到了一个非常奇怪的 For 循环实现。该练习显示了以下语法:

for (Days d: Days.values());

一开始,我以为是语法错误,因为我一直都知道“For循环”的语法需要大括号,或者,如果只有一条指令要迭代,我们可以跳过大括号并设置我们的语句在循环之后对齐。 -- 因为我之前没有见过以分号“;”结尾的 For 循环。--

然后我试图找到一些关于它的文档,但不幸的是我找不到任何解释为什么是合法代码声明。仅引用以下语法:

The syntax of enhanced for loop is:

for(declaration : expression)
{
   //Statements
}

奇怪的是,在所有这些之后,我测试了我的代码,令人惊讶的是它编译并运行正常。然后,根据我所做的一些测试(玩代码),我发现似乎“;”就像一个空的 For 循环,但带有花括号,因此,它之后的任何指令都只执行一次。 (好像代码在哪里循环)。但我不确定这是否是增强 for 循环中分号的正确解释。

请查看完整示例:

package com.TestDays;
public class TestDays {
    public enum Days { MON, TUE, WED};
    public static void main(String[] args) {
    int x = 0;
    *for (Days d: Days.values());*
    Days[] d2 = Days.values();
    System.out.println(d2[2]);
    }

}
  • 有谁知道为什么允许这种语法? 谢谢。

【问题讨论】:

  • 一个for (Days d: Days.values());for (Days d: Days.values()){ //nothing inside the curlies }一样,是一个空的for语句。

标签: java for-loop


【解决方案1】:

https://docs.oracle.com/javase/specs/jls/se7/html/jls-18.html

一个for循环定义为:

  for ( ForControl ) Statement

; 是 Java 中的有效语句,就像语句块一样。这种循环形式不是您经常看到的,但您可以执行以下操作:

 int i = 2;
 for(; i < 100; i*=2);
 // i is now the smallest power of two greater than 100

【讨论】:

    【解决方案2】:

    请注意,在文档中仅提及以下语法:

    The syntax of enhanced for loop is:
    
    for(declaration : expression)
    {
       //Statements
    }
    

    引用您的问题的“文档”来自 TutorialsPoint 上的一个页面(我在 2016 年 5 月 22 日看到)。我不会链接到它,但假设他们还没有更正它(还),你应该能够使用谷歌短语搜索找到它。

    这不是官方文档。 Java 的唯一官方文档是由 Oracle(以及以前的 Sun Microsystems)员工编写并由这些组织发布的文档。

    TutorialsPoint 没有地位。在这种情况下,他们只是弄错了 Java 语法。

    根据 Java 8 JLS,增强型 for 循环的真正 Java 语法是1

    EnhancedForStatement:
        for ( {VariableModifier} UnannType VariableDeclaratorId : Expression ) 
             Statement
    
    EnhancedForStatementNoShortIf:
        for ( {VariableModifier} UnannType VariableDeclaratorId : Expression ) 
             StatementNoShortIf
    

    其中StatementStatementNoShortIf 包含空语句;即一个裸分号。


    1 - 语法规则引用自 Java 8 语法。 “no short ifs”变体是关于消除嵌套 if 语句的歧义,在这里不相关。在 Java 7 JLS 中,规范中有两个版本的语法,一个有变体,一个没有变体。

    【讨论】:

      【解决方案3】:

      您阅读的文档不是官方文档,因为作者会这样写:

      增强的for 语句的形式为for (declaration : expression) statement

      这是因为不需要大括号。

      单个分号形成所谓的_空语句_,这使您的代码 sn-p 在语法上有效。

      【讨论】:

        【解决方案4】:

        在 Java 中创建 for-loopenhanced for-loop 主要有 3 种不同的方式:

        for (int i = 0; i < 5; i++) {
            System.out.println(i);
        }
        
        for (int i = 0; i < 5; i++) System.out.println(i);
        
        for (int i = 0; i < 5; i++);
        

        这3个循环相当于:

        1. 每当i 小于 5 时,执行{} 之间的任何操作并将其值加一。
        2. 每次i 小于 5,打印 i 并将其值加一。
        3. 每当i 小于 5 时,将其值加一。

        这不是“为什么不失败”的问题,而是“告诉 for 循环做什么”的问题。

        具体来说,为什么它不会失败,是for循环语法的布局方式。 Stephen C 的回答很好地解释了这一点:

        根据Java 8 JLS,增强for循环的真正Java语法是

        EnhancedForStatement:
            for ( {VariableModifier} UnannType VariableDeclaratorId : Expression ) 
                 Statement
        
        EnhancedForStatementNoShortIf:
            for ( {VariableModifier} UnannType VariableDeclaratorId : Expression ) 
                 StatementNoShortIf
        

        如您所见,Statement 指的是任何有效的语句,包括; 的用法,因为; 是有效的“Statement”。因为这是允许的,所以在任何情况下都没有理由失败。

        事实上,解释for (int i = 0; i &lt; 5; i++); 的另一种方式是:

        “每当i 小于 5 时,运行语句,并将其值加一。”

        同样的规则可以应用于:

        for (Integer i : ints) {
            System.out.println(i);
        }
        
        for (Integer i : ints) System.out.println(i);
        
        for (Integer i : ints);
        

        【讨论】:

        • 其实很有道理,非常感谢您的解释。
        • @B.Demille 谢谢。如果此答案解决了您的问题,请随时将其标记为已接受。
        • 我没有更新,我还没有15点声望,所以我不能投票。
        • “请解释否决票?” - 不是我,但你的回答实际上并没有回答被问到的问题。 Does anyone knows why this syntax is allowed? - 答案是 OP 依赖于 >>incorrect
        • @B.Demille - 显然,您脑海中问题的“要点”与您实际写出的内容之间存在显着差异。
        猜你喜欢
        • 2012-09-28
        • 2012-07-18
        • 2019-11-03
        • 2011-04-28
        • 1970-01-01
        • 2020-09-11
        • 1970-01-01
        • 1970-01-01
        • 2014-02-23
        相关资源
        最近更新 更多