Есть ли использование свободного плавающего блока внутри метода в Java? - PullRequest
14 голосов
/ 23 декабря 2010

Я не знал, что методы могут иметь плавающие блоки, подобные этому:

class X { 
    public static void main( String [] args ) {
        { //<--- start
            int i;
        } //<-- ends
    }
}

Я знал о плавающих блоках вне методов, но никогда не пробовал их внутри.

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

Есть ли применение для плавающих блоков внутри методов в Java?

Ответы [ 4 ]

15 голосов
/ 23 декабря 2010

Есть ли применение?

Да - для ограничения области действия локальных переменных.

Это хорошая идея?

Вероятно, дискуссионный (и, вероятно, будет).

Лагерь "pro" скажет, что никогда не повредит сузить область действия переменной.Лагерь "con" скажет, что если вы используете его в методе, а ваш метод достаточно длинный, чтобы оправдать сужение области видимости переменных до определенных разделов, то это, вероятно, является признаком того, что вы должны делать отдельные методы из различных разделов,

Лично я ими пользуюсь, например:

public void doGet(
        final HttpServletRequest request,
        final HttpServletResponse response)
  throws IOException {
    final PersistenceManager pm = PMF.get().getPersistenceManager();

    final List<ToDoListGaejdo> toDoLists;
    {
        final Query query = pm.newQuery(ToDoListGaejdo.class);
        query.setOrdering("listName asc");
        toDoLists = (List<ToDoListGaejdo>) query.execute();
    }

    final List<ToDoItemGaejdo> entries;
    {
        final Query query = pm.newQuery(ToDoItemGaejdo.class);
        query.setOrdering("listName asc, priority asc");
        entries = (List<ToDoItemGaejdo>) query.execute();
    }

    final ServletOutputStream out = response.getOutputStream();

    out.println("<head>");
    out.println("  <title>Debug View</title>");
    ....
4 голосов
/ 23 декабря 2010

Вы только что привели пример сами.Вы можете сделать объявление i «более локальным», чем область действия метода.Когда он выходит из области видимости, остальная часть метода не видит его.

Синтаксически, блок может появляться везде, где может появиться оператор.Это фундаментальный принцип блочно-структурированных языков.

3 голосов
/ 23 декабря 2010

Еще один случай, когда блоки полезны, это операторы switch;например, следующее недопустимо

    switch (i) {
      case 1:
        float j = ...;
        break;
      case 2:
        float j = ...;  // compilation error
        break;
      ...
    }

, но оно нормально с добавленными блоками:

    switch (i) {
      case 1:
        {
          float j = ...;
          break;
        }
      case 2:
        {
          float j = ...;  // just fine
          break;
        }
      ...
    }

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

  • с использованием одного и того же имени для одной и той же концепции (хотя и в другой области видимости) в обычном коде, подобном этому, хорошо для крупномасштабныхудобочитаемость и
  • использование блоков облегчают компиляторам распознавать, что объявленные переменные могут совместно использовать слоты фреймов стека.Это потенциально важно, если метод включения также является рекурсивным.

(ОК, все это либо микрооптимизация, либо следствие микрооптимизации. Но давайте предположим, что мы определили, что это оправдано.)

3 голосов
/ 23 декабря 2010

Да, они полезны для двух целей.

Во-первых, вы можете ограничить область видимости переменных, используя такие блоки.Это может помочь с удобочитаемостью кода, потому что у вас есть меньшая область, которую следует учитывать при определении того, как используется переменная.Кроме того, это может минимизировать необходимое количество «слотов» для фрейма метода, сохраняя пространство стека.Я был бы очень удивлен, обнаружив случай, когда эта оптимизация была необходима.

Во-вторых, когда вы прикрепляете метку к блоку, целевая break может использоваться внутри блока, чтобы перейти к концублок.Это не вполне столь же зло, как чистое утверждение goto, но прицел все еще вызывает красные флаги и предупреждающие звонки.

...