2 февраля 2012 г.

Инициализация double brace

Во всех языках программирования существуют красивые, лаконичные и простые конструкции, составляющие основу языка, а есть "хаки", глядя на которые невольно вспоминаешь собеседования и вопросы вида "вот вам 5 строк кода и 10 минут на то, чтобы объяснить как это вообще работает". Об одной из таких конструкций, а именно об инициализации double brace я и хотел бы сегодня рассказать.

Допустим вы хотите создать коллекцию с набором констант. Для этого в классе вы можете написать что-то типа:
private static final Set<String> SOME_CODES = new HashSet<String>();
static {
    SOME_CODES.add("code1");
    SOME_CODES.add("code2");
    SOME_CODES.add("code3");
    SOME_CODES.add("code4");
}
Довольно неуклюжая запись, неправда ли? К тому же наполнение контейнера вынесено за пределы его создания, что само по себе чревато ошибками. Тут-то на помощь нам и приходит double brace инициализация! Можно переписать это выражение так:
private static final Set<String> SOME_CODES = new HashSet<String>() {{
    add("code1");
    add("code2");
    add("code3");
    add("code4");
}};
Выглядит просто. Но что же тут произошло? Первая скобка создает анонимный внутренний класс (напомню, что анонимные внутренние классы можно создавать не только от интерфейсов, но и от классов), а вторая - блок инициализации, который вызывается на этапе инстанцирования класса. Внутри этого блока вы можете использовать любые методы и поля класса, помня о том, что блок статической инициализации выполняется ДО вызова конструктора класса (но после конструктора суперкласса).

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

Все это довольно сложно на мой взгляд и заставляет лишний раз отвлекаться от решения более важных проблем. К счастью, для создания коллекции с набором констант, мы можем просто сделать так:
List<String> SOME_CODES = new ArrayList<String>(
                      Arrays.asList("code1", "code2", "code3", "code4"));
Всё просто, лаконично и очевидно. Так что, как говорится, KISS.

4 комментария:

  1. Блин, хотел написать "здесь был я", но протупил. А редактировать комменты оно не даёт. :(

    ОтветитьУдалить
    Ответы
    1. Спасибо за текст того первого коммента. Исправил. :)

      Удалить
  2. Может тебе будет интересно: http://t.co/Kx7UPc1y
    Я просмотрел по диагонали и понял, что всё еще хуже, чем я думал. А чтобы все было хотя бы более-менее приемлемо, надо проявлять нехилую сноровку.

    ОтветитьУдалить
  3. List SOME_CODES = Arrays.asList("code1", "code2", "code3", "code4");

    почему так не использовали? ^

    ОтветитьУдалить

Примечание. Отправлять комментарии могут только участники этого блога.