1

在用 Java 编写另一个do ... while循环时,我开始思考它的语法。一个典型的程序员会写类似

do {
  somethng();
}while(booleanValue);

然而,Java 有一种内置的压缩​​方式,允许程序员在循环内只有一行时删除大括号(这对于 Java 表达式很典型):

do
  something();
while(booleanValue);

这可以被认为和写成

do something();
while(booleanValue);

甚至作为

do;
while(booleanValue);

这很有趣。这引起了我的注意,这是一个必须跨两行读取和运行的 Java 语句,这意味着在运行该行之后do,直到该行运行时操作才完成while。请记住,其他表达式只有一行:

if(booleanValue) something();
while(booleanValue) something();
for(Object declaration; booleanValue; operation()) something();
for(Object declaration : iterableObject) something();
throw throwableObject;
return anyObject;
switch(integer) {}
//case is excluded because it operates a lot more like a goto operation than a statement

所以我开始思考,不是关于为什么会这样,而是关于如何进一步压缩这个陈述。

假设“行”是以分号 ( ;) 结尾或包含在大括号 ( {and }) 中的任何内容,让我们了解这一点:一条do语句必然需要运行两行,一条do语句必须至少继续运行直到它到达一个空while语句

那么为什么要使用牙套呢?

让我们看一些使用这种语法的场景。do...while带有一个封闭语句的语句怎么样:

do something();
while(booleanValue();

好吧,这里没有什么新鲜事。do...while带有三个封闭语句的语句怎么样:

do
  statement1();
  statement2();
  statement3();
while(booleanValue);

在这里,Java 将看到它是一个语句,它会在看到空语句do之前运行第 2、3 和 4 行。while此时,它知道我们已准备好结束循环,计算表达式,并可能返回do或退出循环。

您可能认为会破坏它的东西怎么样?嵌套while循环:

do
  statement1();
  while(booleanValue1)
    statement2();
while(booleanValue2);

在这里,Java 看到它是一个do语句并输入它,然后正常运行第 2 行。在 line 3,它看到它是一个while语句。此时它必须决定这是否是循环的结束。它检查while语句并发现它不是空的,因此不是do循环的结尾。它进入while语句并循环第 3 行和第 4 行,直到不再循环。然后它会看到另一个while语句,并且在检查时发现它是空的,因此是do语句的结尾。它评估它,可能会或可能不会返回到第 2 行,但我们现在不在乎。

但是Supuhstar,这肯定看起来很多计算!这不会减慢 JVM 的速度吗?

不必要!这都可以在编译时完成,就像 Java 确定上面列出的任何其他语句是否为空(例如,尝试编译while(true);将导致下一行编译时出现错误“ unreachable statement”)。

所以,很像

for(Object declaration : iterableObject)
  somethingInvolving(declaration);

编译成

Iterator<Object> i = iterableObject.iterator();
while(i.hasNext())
{
  Object declaration = i.next();
  somethingInvolving(declaration);
}

然后

do
  statement1();
  while(booleanValue1)
    statement2();
while(booleanValue2);

可以编译成

do
{
  statement1();
  while(booleanValue1)
  {
    statement2();
  }
}
while(booleanValue2);

但是 Supuhstar,Java 不关心缩进!你的可以写任何缩进,或者根本没有?

当然!编译器同样容易编译

do
  statement1();
  while(booleanValue1)
    statement2();
while(booleanValue2);

就像它会

do statement1(); while(booleanValue1) statement2(); while(booleanValue2);

这两者都会做同样的事情。

是否有其他人同意将这作为 Java 语法包含在内是一件好事,或者是否有一些明显的原因我错过了这不能完成?

4

3 回答 3

3

想想这段代码

    if(true)
        if(false)
            System.out.println("x");
    else
        System.out.println("y");

它打印“y”。有时,对于没有牙套的人来说,这太令人困惑了。

于 2012-10-10T23:11:37.157 回答
2

这个特别的陈述让我感到有些困惑:

它检查 while 语句并发现它不是空的,因此不是 do 循环的结尾。

因为“不空”是什么意思?while 循环允许为“空”:

do
  statement1();
while(booleanValue1);
while(booleanValue2);

即使第一个while循环会关闭do-while而不是第二个,这在您的计划下也是有效的。

话虽这么说,你建议的语法不会模棱两可,我不认为....但没关系,因为它永远不会被引入,因为语言设计者没有(也从来没有)有兴趣让 Java 成为更简洁或更简洁的语言。

您甚至可以说冗长是 Java 哲学的基本组成部分。编译器可以推断或允许但不能推断出许多事情。好消息是有很多更现代的语言,比如 Scala,可以让你编写更简短、更有表现力的代码。

于 2012-10-10T23:07:08.393 回答
1

与不受欢迎的说法类似,我也看过这个例子:

if(false)
    //System.out.println("x");

System.out.println("Done");

你能明白为什么第二次打印没有运行吗?

于 2013-07-23T08:05:28.700 回答