Java синтаксический сахар - PullRequest
       7

Java синтаксический сахар

12 голосов
/ 05 октября 2010

Сегодня я столкнулся с этим блоком кода, и я не знаю, как он работает.Я знаю, как создавать анонимные классы, но я привык видеть сигнатуру метода, а не просто пару скобок.Код между этими скобками помещен в статический блок?Это входит в конструктор?Или это что-то совсем другое?

conext.checking(new Expectations() {
    { // <- what does this pair of braces do?
        oneOf(alarm).getAttackAlarm(null);
    }
});

Ответы [ 7 ]

17 голосов
/ 05 октября 2010

Это инициализатор экземпляра, который вызывает код в контексте созданного объекта.

Это эквивалентно

Expectations exp = new Expectations();
exp.oneOf(alarm).getAttackAlarm(null);
conext.checking(exp)

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

Основное место, которое эти инициализаторы полезны, как это, при создании экземпляров карт, то есть:

Map map = new HashMap() {{
  put("key1", "value1");   
  put("key2", "value2"); 
}};

Я думаю, что на самом деле это немного более читабельно.

4 голосов
/ 05 октября 2010

Это блок инициализатора, но не обязательно статический блок инициализатора.Это фактически конструктор для анонимного внутреннего класса.Обычно вы будете видеть этот шаблон «двойной скобки инициализации» для удобного создания и заполнения коллекций:

private final Collection<Integer> FIXED_COLLECTION = Collections.unmodifiableCollection(new HashSet<Integer>() 
{ // first set of braces declares anonymous inner class
    { add(1); add(2); add(3); } // second set is initializer block
});
3 голосов
/ 05 октября 2010

Это инициализатор экземпляра (не статический инициализатор).

Рассмотрим определение класса

public class Foo {
    private int i = getDefaultValue();

    private static int getDefaultValue() {
        return 5;
    }
}

Вызов getDefaultValue(), который инициализирует i, по сути является кодомблок, который запускается каждый раз, когда создается экземпляр Foo.Система обозначений расширяет эту функцию, чтобы обеспечить более сложную инициализацию.Например,

public class Foo {
    private int i;

    {
        int z = 4 + 5;
        i = z + getDefaultValue();
    }

    private static int getDefaultValue() {
        return 5;
    }
}

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

1 голос
/ 05 октября 2010

Что происходит?Скобки external создают новый анонимный класс, производный от Exception. внутренние фигурные скобки определяют инициализатор и устанавливают oneOf() и т. Д.

Почему это происходит?Это однострочный трюк для создания и инициализации экземпляра класса.е.иногда вы видите что-то вроде этого:

new Set<String>(){{add("one");add("two")}}

для инициализации содержимого коллекции.

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

0 голосов
/ 06 октября 2010

Я полагаю, что основной причиной этого является создание нового пространства имен, в котором к именам, определенным в Expection, проще обращаться.

Например, предположим, что java.lang.Math не является окончательным,

new Math()
{{
    double x = sin(23.65);
    double y = log(x);
    ...
}};

Это почти как если бы у нас было что-то вроде

with names from Math
{
    double x = sin(23.65);
    double y = log(x);
    ...
}
0 голосов
/ 05 октября 2010

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

0 голосов
/ 05 октября 2010

Это блок инициализатора. Я не могу сказать, что он делает, не глядя на остальную часть кода.

Хитрость заключается в том, чтобы представить, что «новое ожидание ()» заменено на «класс Что-то расширяет ожидание».

...