Java для чего нужна двойная нотация? - PullRequest
9 голосов
/ 14 сентября 2011

Я просматривал Интернет и нашел этот пример . В публичном методе static void main есть синтаксис этой строки, который я никогда раньше не видел __main:

Как в:

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

Я попытался вставить это в затмение и получил небольшое желтое подчеркивание с подсказкой, которая гласила: «На метку __main никогда явно не ссылаются».

Я ничего не могу найти онлайн и мне действительно любопытно! Я программировал на Java годами и никогда раньше не видел этот синтаксис. Что он делает, зачем вы его используете, где я могу узнать больше?

Ответы [ 8 ]

11 голосов
/ 14 сентября 2011

Это метка .Вы можете использовать его с операторами break и continue.Нет необходимости использовать двойное подчеркивание.


Точнее, это (первая) часть помеченного оператора ( JLS 14.7 )):

Identifier : Statement
4 голосов
/ 14 сентября 2011

Двойные подчеркивания в Java не имеют семантического значения (так же, как одиночные подчеркивания не имеют никакого семантического значения).

Единственное значение, которое они могут иметь , будет зависеть от некоторого соглашения об именах, определяющего, для чего они используются.

Похоже, что код, который вы просматриваете, использует двойные подчеркивания для меток. Поскольку ярлыки не часто используются в Java, я бы не стал сильно беспокоиться об этом.

2 голосов
/ 14 сентября 2011

A goto оператор в C и его аналоги сопровождаются аргументом Label .В определенном методе оператор goto label; запустит процедуру, выполняющую метку.Ниже приведен пример, продемонстрированный Грегом Роджерсом в этой публикации .

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

    // everything succeed
    return;

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

A goto может быть очень эффективным инструментом в 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, я не использовал его лично, но я думаю, что он может помочь в достижении той же структуры кода, что продемонстрировал Грег Роджерс, например:

 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;}
2 голосов
/ 14 сентября 2011

В Java есть метки (но нет перехода). Двойное подчеркивание не имеет смысла, но это допустимый идентификатор Java.

Из JLS:

14.7 Помеченные заявления В заявлениях могут быть префиксы для этикеток.

LabeledStatement:
  Identifier : Statement

LabeledStatementNoShortIf:
  Identifier : StatementNoShortIf

Идентификатор объявляется как метка Содержимое заявление.

В отличие от C и C ++, язык программирования Java не имеет оператора goto; метки операторов идентификатора используются с break (§14.14) или continue (§14.15) операторы, появляющиеся в любом месте внутри помеченного оператора.

Область действия метки, объявленной помеченным оператором, - это оператор сразу же сопровождается помеченным заявлением.

2 голосов
/ 14 сентября 2011

Двойные подчеркивания не имеют значения. Вы действительно спрашиваете о ярлыках. Вот некоторая информация . В основном они используются для контроля перерывов. Также забавный вопрос пустяков в интервью: компилируется ли следующий код?

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

Почему да, и теперь вы знаете, почему: D

2 голосов
/ 14 сентября 2011

Это просто ярлык. Вы можете написать bla:, для того же эффекта.

Метки обычно используются с goto утверждениями, но, насколько я знаю, goto запрещен в Java (и очень не рекомендуется на любом другом языке высокого уровня).

Однако это также можно использовать внутри циклов с continue и break, например, continue someLabel;, если вы хотите, чтобы продолжение или разрыв ссылались на внешний цикл, а не на тот, в котором вы сейчас находитесь.

1 голос
/ 20 ноября 2012

Никто, похоже, не ответил ТОЧНО на то, что вы на самом деле спросили (но ответы "goto" - это, вероятно, то, что вы действительно искали), и они правы в том, что это просто идентификатор, но не почему они использовались в этом случае.

Двойное подчеркивание обычно используется в системе для предотвращения возможных коллизий с другими идентификаторами ... обычно оно используется в тех случаях, когда область действия доступна пользователю. В этом случае без подчеркиваний вам может быть запрещено делать «основную» переменную в той или иной точке, или, возможно, некоторые системные классы не смогут использовать слово main.

В этом случае я предполагаю, что, если бы переменная была названа "main", это конфликтовало бы с определением "public static void main".

Полагаю, что двойное подчеркивание является формой ручного определения масштаба.

1 голос
/ 14 сентября 2011

двойное подчеркивание и метки, как правило, чаще используются в Си. Возможно, разработчик недавно писал С.

Кстати: метки редко используются для циклов, но еще более редким является выпрыгивание из области видимости.

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

Поскольку ярлыки встречаются редко, они могут сбивать с толку, а не приносить пользу.;)

...