Что действительно делает {{синтаксис в инициализаторе ArrayList - PullRequest
5 голосов
/ 08 декабря 2010

Недавно я нашел то, что мне кажется новым синтаксисом для статической инициализации ArrayList:
new ArrayList() {{ add("first"); add("second"); }};

Мой вопрос: что там на самом деле происходит? Это ярлык для определения статического блока (я думал, что понадобится ключевое слово static)? Или просто способ определить конструктор по умолчанию? Что-то другое? Какая версия Java стала действительной?

Объяснение плюс ссылка на дальнейшее чтение будет с благодарностью.

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

import org.junit.Test;

public class InitializerBlockTest {
    class InitializerTest {
        {
        System.out.println("Running initalizer block");
        }

        public InitializerTest() {
            System.out.println("Running default constructor");
        }
    }

    class SubClass extends InitializerTest {
      {
        System.out.println("Running subclass Initializer block");
      }

      public SubClass()  {
        System.out.println("Running subclass constructor");
      }
    }

    @Test
    public void testIt() {
        new SubClass();
    }
}

Выход:

Running initalizer block
Running default constructor
Running subclass Initializer block
Running subclass constructor

Ответы [ 3 ]

6 голосов
/ 08 декабря 2010

Вы создаете новый анонимный подкласс ArrayList с инициализатором экземпляра, который дважды вызывает add ().

Это так же, как:

class MyList extends ArrayList
{

{ // This is an instance initializer; the code is invoked before the constructor.
add("first"); 
add("second");
}

public MyList() {
    super();
    // I believe initializers run here, but I have never specifically tested this
    }
}

...

List list=new MyList();

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

4 голосов
/ 08 декабря 2010

Это блок инициализатора для переменных экземпляра.

Из документации Oracle:

Блоки инициализатора для переменных экземпляра выглядят так же, как статические блоки инициализатора, но без ключевого слова static:

{

    // whatever code is needed for initialization goes here
}

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

См .: http://download.oracle.com/javase/tutorial/java/javaOO/initial.html

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

Когда вы пишете new ArrayList() { }, вы создаете анонимный подкласс ArrayList.{ }, как в самых внутренних скобках вашего кода, обозначает блок инициализатора и фактически копируется в каждый конструктор.

РЕДАКТИРОВАТЬ: Вы, ребята, обязательно отвечаете быстро!

...