关于java:与else语句不一致?

Inconsistency with else statements?

这是我之前问题的修订版。

当使用else-if作为快捷方式时,我不完全确定为什么,语法方面,它执行与嵌套if-else语句相同的功能。 假设您有以下内容:

1
2
3
4
5
6
7
8
int score = 80;
if(score < 80) {
  System.out.println("C Grade");
} else if(score < 90) {
  System.out.println("B Grade");
} else if(score < 100) {
  System.out.println("A Grade");
}

如果我添加一些缩进,我得到类似的东西:

1
2
3
4
5
6
7
8
9
if(score < 80) {
  System.out.println("C Grade");
} else
  if(score < 90) {
    System.out.println("B Grade");
  } else
    if(score < 100) {
      System.out.println("A Grade");
    }

这与编写嵌套的if-else语句的结果相同:

1
2
3
4
5
6
7
8
9
10
11
if(score < 80) {
    System.out.println("C Grade");
} else {
    if(score < 90) {
        System.out.println("B Grade");
    } else {
        if(score < 100) {
        System.out.println("A Grade");
        }
    }
}

然而,我看到了一个重大的区别。 在第三个代码片段中,"else"语句有括号,其余的if-else语句嵌套在这些括号中。 在第一种情况下,没有封装括号。 那么,为什么第一个想法是else-if work,如果我在嵌套if-else语句时看似需要括号? 我认为缺少括号与控制流语句,如if,else,while等导致编译器只评估以下行,例如:

1
2
3
4
if(condition)
    System.out.println("A");
    System.out.println("B");
//only prints"A"


如果没有括号,则使用以下语句,而不仅仅是以下行。

if语句包含

1
if (<condition>) <statement> else <statement>

它是否写在几行上并不重要。通常,在允许使用空格而不改变含义的任何地方,Java都可以发生换行符(唯一的例外是字符串文字和一行注释)。


支架不是流量控制机制。它们主要是一种语句分组机制。

简单if else语句的语法是:

1
'if' '(' expression ')' statement 'else' statement

'statement'可以是赋值语句,方法调用,嵌套if等。但'声明'不是两个陈述,或三个,或......

这是{ }进入它的地方,因为

1
'{' statement-list '}'

根据Java语法规则实际上是statement。通过使用大括号,您可以将(可能)许多语句分组到单个语句中。

如果您将这些知识应用于您的示例,您认为您所看到的"神秘"行为将变得简单直接。

对于记录,建议您始终使用带有if语句和循环的{ }块,因为它使您的代码更易于阅读。

I thought that a lack of brackets with control flow statements such as if, else, while, etc. cause the compiler to only evaluate the following line.

你得出了一个错误的结论。在Java语言中,它(几乎)与您放置换行符的代码的含义无关。唯一的限制是你不能在代码中间放置换行符,如关键字,运算符,标识符和文字。 (并且换行结束//评论。)

顺便说一句,尝试通过阅读文本和猜测语法来学习编程语言是一种糟糕的方法。你会有各种不正确的想法。更好的方法是阅读一本好的教科书或该语言的官方教程材料。


首先,请注意ifelse始终适用于它后面的单个语句。您可以使用{ }将多个语句分组到单个复合语句中,但条件则适用于单个{ ... }语句。

考虑这两个等价的陈述:

1
2
3
4
5
6
if (foo) {
  bar();
}

if (foo)
  bar();

在第一个中,if适用于{ }块(包含bar();),而在第二个中,它直接应用于bar();语句。可能不会立即显而易见的是{ }不是创建复合语句的唯一方法。实际上,if是另一个复合表达式,因此它可以是另一个ifelse语句的直接子节点。例如:

1
2
3
4
if (foo)
  if (bar) {
    baz();
  }

完全有效(如果难以阅读)并且相当于:

1
2
3
4
5
if (foo) {
  if (bar) {
    baz();
  }
}

同样的概念对于else也是如此 - 如果前面的条件为假,即使该语句本身就是一个复合语句,它将被应用。

1
2
3
4
5
6
7
if (foo) {
  bar();
}
else
  if (baz) {
    biff();
  }

else适用于整个if (baz)块,因为它只是一个(复合)语句,所以不需要额外的{ }块。

确切的语法在JLS§19中指定,if语句的不同形式的语法在JLS§14.9中详述。请注意,没有提到else if,因为它不是语言的正式部分,只是语法的(故意)后果。

所有这些都说,我们不按照你描述的方式格式化代码的真正原因仅仅是因为它更难阅读。将else if视为单个关键字并相应缩进代码要简单得多。其他一些语言(例如Python)使用单个关键字(如elif)来简化语法,但这并不是必需的。