10

我在浏览网页时发现了这个例子。在 public static void main 方法中是我以前从未见过的这一行语法__main:

如:

public class Klass {
    public static void main(String[] args) {
        // code goes here...
__main:
        // and mode code here...
    }
}

我尝试将其打入 eclipse 并得到一个带有工具提示的黄色下划线,上面写着“标签 __main 从未被明确引用”。

我在网上找不到任何东西,我真的很好奇!我已经用 Java 编程多年了,以前从未见过这种语法。它有什么作用,为什么要使用它,我在哪里可以了解更多信息?

4

8 回答 8

12

那是一个标签。您可以将它与breakandcontinue语句一起使用。没有必要使用双下划线。


更准确地说:它是标签声明JLS 14.7)的(第一)部分:

Identifier : Statement
于 2011-09-14T08:25:48.547 回答
5

Java 中的双下划线没有语义含义(就像单下划线没有任何语义含义一样)。

它们可能具有的唯一含义将取决于一些定义它们用途的命名约定。

看起来您查看的代码使用双下划线作为标签。由于标签在 Java 中不经常使用,因此我不会太担心。

于 2011-09-14T08:25:16.143 回答
2

这只是一个标签。你可以写bla:, 达到同样的效果。

标签通常与goto语句一起使用,但据我所知,goto在 java 中是被禁止的(并且在任何其他高级语言中都非常不鼓励使用)。

但是,这也可以在带有continueand的循环内使用break,例如continue someLabel;,如果您希望 continue 或 break 引用外部循环而不是您现在所在的直接循环。

于 2011-09-14T08:26:08.353 回答
2

双下划线无关紧要。你真的在问标签。这是一些信息。基本上它们用于控制休息时间。面试中还有一个有趣的琐事问题:以下代码是否编译?

public void doSomething(){
   http://www.stackoverflow.com
}

为什么是的,现在你知道为什么了:D

于 2011-09-14T08:28:01.270 回答
2

Java 有标签(但没有 goto)。双下划线没有任何意义,但它是合法的 Java 标识符。

来自 JLS:

14.7 标签语句 语句可能有标签前缀。

LabeledStatement:
  Identifier : Statement

LabeledStatementNoShortIf:
  Identifier : StatementNoShortIf

标识符被声明为立即包含的语句的标签。

与 C 和 C++ 不同,Java 编程语言没有 goto 语句;标识符语句标签与出现在标记语句中的任何位置的 break (§14.14) 或 continue (§14.15) 语句一起使用。

由带标签的语句声明的标签的范围是由带标签的语句直接包围的语句。

于 2011-09-14T08:28:08.553 回答
2

C 中的goto语句及其对应语句伴随着一个Label参数。在定义的方法中,goto label;语句将触发执行标签的例程。以下是 Greg Rogers 在这篇文章中演示的示例。

void foo()
{
    if (!doA())
        goto exit;
    if (!doB())
        goto cleanupA;
    if (!doC())
        goto cleanupB;

    // everything succeed
    return;

cleanupB:
    undoB();
cleanupA:
    undoA();
exit:
    return;
}

Agoto在 Java 中可能是一个非常有效的工具,但 Java 并不明确支持该goto关键字,即使该关键字已被语言保留。使用break语句将使命令跳出标签继续执行标签后面的语句。

例子:

public class Klass {
  public static void main(String[] args) {
  // code goes here...
  __main:
        {
         if(args.length==0)
         {
          break __main;
         }
        }
  //code after label
    }
}

这个包com.sun.org.apache.bcel.internal.generic.GOTO,我没有亲自使用过,但我认为它可以帮助实现与 Greg Rogers 演示的相同的代码结构,如下所示:

 void foo()
  {
      if (!doA())
          GOTO exit;
      if (!doB())
          GOTO cleanupA;
      if (!doC())
          GOTO cleanupB;

      // everything succeed
      return;

  cleanupB:
      undoB();
  cleanupA:
      undoA();
  exit:
      return;
  }

  void undoB(){}
  void undoA(){}
  boolean doC(){return false;}
  boolean doA(){return false;}
  boolean doB(){return false;}
于 2011-09-14T08:47:51.607 回答
1

双下划线和标签往往在 C 中使用较多。也许开发人员最近一直在写 C。

顺便说一句:标签很少用于循环,但更罕见的用途是跳出范围。

scope: {
  // some code
  if (flag)
      break scope; // no loop
  // some more code
}

因为标签很少见,它们可能比有用更令人困惑。;)

于 2011-09-14T08:38:19.720 回答
1

似乎没有人确切地回答了您实际提出的问题(但“goto”答案可能是您真正想要的)并且他们认为它只是一个标识符是正确的,但不是在这种情况下使用它们的原因。

双下划线通常在系统中使用,以防止与其他标识符可能发生冲突......通常用于用户可以使用范围的情况。在这种情况下,如果没有下划线,您可能无法在某些时候创建“主”变量,或者可能会阻止某些系统类使用 main 一词。

在这种情况下,我猜测如果变量被命名为“main”,它将与定义的“public static void main”冲突。

我想总而言之,双下划线是手动范围界定的一种形式。

于 2012-11-20T18:32:43.187 回答