Что означают фигурные скобки в Java сами по себе?

У меня есть код Java, в котором фигурные скобки используются двумя способами.

// Curly braces attached to an 'if' statement:
if (node.getId() != null)
{
    node.getId().apply(this);
}

// Curly braces by themselves:
{
    List<PExp> copy = new ArrayList<PExp>(node.getArgs());
    for(PExp e : copy)
    {
        e.apply(this);
    }
}
outAMethodExp(node);

Что означают эти отдельные фигурные скобки после первого оператора if?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
79
0
42 424
11
Перейти к ответу Данный вопрос помечен как решенный

Ответы 11

Они составляют внутреннюю область. Переменная, объявленная внутри этих фигурных скобок, не видна вне их. Это также относится к C / C++.

Я думаю, они просто определяют безымянный уровень охвата.

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

Ответ принят как подходящий

Единственная цель дополнительных фигурных скобок - обеспечить ограничение области действия. List<PExp> copy будет существовать только в этих фигурных скобках и не будет иметь никакой области действия за их пределами.

Если это сгенерированный код, я предполагаю, что генератор кода делает это, чтобы он мог вставить некоторый код (например, этот), не беспокоясь о том, сколько раз он вставлял List<PExp> copy, и не беспокоясь о возможном переименовании переменных, если это фрагмент вставляется в один и тот же метод более одного раза.

Дополнительным «преимуществом» в этом случае является то, что copy может быть собран перед возвратом outAMethodExp(). Если это длительный вызов или вызов, требующий интенсивного использования памяти, это может быть полезно. Я заключил «выгоду» в кавычки, потому что рефакторинг в отдельные методы, как правило, намного чище и понятнее, чем использование преимуществ этого синтаксиса.

dimo414 17.02.2015 00:56

Фактически, определение области видимости переменной влияет на сборку мусора нет. Во всех известных мне современных JVM JIT может определить, что объект имеет право на сборку мусора, независимо от наличия или отсутствия конструкций области видимости, таких как фигурные скобки.

Daniel Pryden 19.10.2016 12:46

На самом деле я предполагаю, что кто-то забыл заявление else.

Редко есть веская причина даже потрудиться с созданием дополнительных областей видимости блока. В этом и в большинстве случаев гораздо более вероятно, что кто-то забыл ввести свой управляющий оператор, чем что он сделал что-то умное.

Я голосую за вас просто потому, что это может случиться, произошло, а Оккам катится в могиле, потому что вас проголосовали против. :)

willasaywhat 27.10.2008 22:53

Он генерируется SableCC. Бьюсь об заклад, 5 $ они не забыли еще

Pavel Feldman 27.10.2008 23:47

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

jayunit100 06.12.2011 23:21

Я отмечаю курсовую работу по java в университете и вижу, что на самом деле это часто именно та причина, по которой она встречается в коде. При повторном факторинге люди иногда вырезают / вставляют, а затем видят неправильное количество скобок ... просто добавьте одну ... а затем посмотрите, что у вас получится. По этой причине я голосую за это. Не всегда заявление else, но часто просто ошибка.

ThePerson 14.03.2013 16:05

Я проголосовал за вас, потому что -1 голос означает, что вы даже не должны были участвовать. Возможно, вы не знали, но вы приложили усилия. Я не о трофеях для всех, но «спасибо» - это как раз то, что я говорю людям, которые пытаются помочь. (+1 == спасибо).

user426364 02.07.2014 22:47

Хотя в данном случае это не так (сгенерированный код), я уверен, что такое часто случается, поэтому +1

k_g 03.04.2015 23:06

Я зарабатываю на жизнь программированием почти 18 лет. Я ни разу не видел, чтобы кто-то забыл контрольное утверждение - заметьте, только в домашних заданиях студентов. «Редко есть веская причина ...» - это сразу вводит в заблуждение - иногда определение объема более читабельно, чем рефакторинг для разделения методов. Кроме того, вы можете захотеть охватить некоторых местных жителей, а не других. Без определения объема вы получите "творческое" именование, такое как tmpList1, tmpList2 и т. д.

user625488 29.01.2016 19:18

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

Интересное примечание: фигурные скобки фактически включают класс операторов: объявления.

Это незаконно: if (a) int f;

но это законно: if (a) { int f; }

Именно этот код бесполезен, вы не сможете увидеть f за пределами фигурных скобок. И чтобы использовать его, вам нужно объявить и использовать его в той же области. Итак, вам нужно более одного утверждения, поэтому вам нужны фигурные скобки.

Pavel Feldman 28.10.2008 00:46

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

Hugo 28.10.2008 05:08

А как насчет if (userWantsTocInReport) {new Toc (report};}? Я не говорю, что это идеальный способ его написания, но это возможность, которую кто-то может выбрать по любой причине.

user625488 29.01.2016 19:26

Я вторю тому, что написал Мэтт Б., и добавлю, что еще одно использование анонимных скобок, которое я видел, - это объявление неявного конструктора в анонимных классах. Например:

  List<String> names = new ArrayList<String>() {
    // I want to initialize this ArrayList instace in-line,
    // but I can't define a constructor for an anonymous class:
      {
        add("Adam");
        add("Eve");
      }

  };

Некоторые фреймворки для модульного тестирования подняли этот синтаксис на другой уровень, что позволяет некоторым хитрым вещам, которые выглядят совершенно некомпилируемыми, работать. Поскольку они Посмотрите незнакомы, я сам не такой большой поклонник, но стоит хотя бы понять, что происходит, если вы столкнетесь с этим использованием.

Извините, я не понимаю этот код. «Добавить» класс или функцию. Если это функция: к какому классу она принадлежит? Принимает ли ArrayList тип делегата в этом случае?

Peter Mortensen 03.08.2009 22:50

«добавить» - это функция. Материал в фигурных скобках вызывается перед конструктором для выполнения некоторой предварительной инициализации. Вы можете проверить c2.com/cgi/wiki?DoubleBraceInitialization, чтобы узнать больше.

Zaven Nahapetyan 17.12.2010 03:34

Технически конструктор вызывается первым, а блок инициализации экземпляра вызывается сразу после вызова super(...).

Oli 30.03.2015 14:14

Я согласен с ответом на ограничение объема, но хотел бы добавить одну вещь.

Иногда вы видите подобную конструкцию в коде людей, которые любят сворачивать разделы своего кода и имеют редакторы, которые автоматически складывают фигурные скобки. Они используют его для сворачивания своего кода в логические секции, которые не попадают в функцию, класс, цикл и т. д., Которые обычно сворачиваются.

Он также используется для блоки инициализации.

Вероятно, стоит упомянуть, что это только для инициализации статического класса вне конструктора. Фрагмент кода OPs находится в блоке метода (единственное возможное место для него).

mmoore 14.03.2013 22:39

Блок инициализации предназначен для инициализации статического класса, если ему предшествует static, в противном случае это блок инициализации пример.

Gabriel 15.03.2013 02:29

Правдивые сказки. Благодарю за разъяснение.

mmoore 15.03.2013 14:54

Скобки также полезны для уменьшения объема в операторах switch / case.

switch(foo) {
  case BAR:
     int i = ...
     ...
  case BAZ:
     int i = ... // error, "i" already defined in scope
}

Но ты можешь написать

switch(foo) {
  case BAR:{
     int i = ...
     ...
  }
  case BAZ:{
     int i = ... // OK
  }
}

Другие вопросы по теме