2013-06-08 4 views
20

Просто интересно о причине компиляции кода:В чем разница между инициализатором экземпляра и конструктором?

class MyClass extends AnotherClass { 
    { 
    MySecondClass object = new MySecondClass(); 
    object.doSomething(); 
    } 
} 

Что разница между этим кодом и кодом в конструкторе? Этот код выполняет до создания объекта.

+0

Я уже некоторое время размышлял об этом, я помню, что видел это некоторое время назад ... кто-нибудь знает, что называется этой структурой? – SimonT

+1

Он называется «блок инициализатора». На самом деле это просто скопировано в каждый конструктор. – wchargin

+1

Этот вопрос может быть дублирующимся вопросом: http://stackoverflow.com/questions/16128076/instance-initialization-block-and-subclasses –

ответ

22

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

Быстрый пример:

public class Foo { 
    { 
     System.out.println("Before Foo()"); 
    } 

    public Foo() { 
     System.out.println("Inside Foo()"); 
    } 

    { 
     System.out.println("Not After Foo()"); 
    } 
} 
+5

Он идет перед каждым конструктором. ('javap -c' скажет вам это.) – millimoose

+0

@millimoose true, ответ исправлен. –

+1

+1 для примера. – Maroun

3

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

Просто интересно о причине компиляции кода, как это:

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

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

+0

Нет, конечно, я не планировал использовать его вместо конструктора. Это был простой интерес, не более того. И спасибо за объяснение перегрузки конструктора. – Oldestkon

+1

Добро пожаловать. Вероятно, вы это уже знаете. Существуют также статические блоки init, которые используются для инициализации статических членов класса. И несколько блоков выполняются в том порядке, в котором они отображаются в вашем коде. –

+0

Я уже знаю основы, на данный момент я изучаю «глубины» многопоточности, такие как летучие вары или синхронизированные блоки. – Oldestkon

12

Это инициализатор экземпляра . Код в инициализаторе вставлен после вызов конструктора суперкласса и до остальная часть кода конструктора.

Первая операция любого конструктора заключается в вызове конструктора суперкласса. Если конструктор явно вызван, используется super(...), указанный конструктор. Если конструктор явно не вызывается, конструктор по умолчанию (без аргументов) вызывается в суперклассе. Если такой конструктор не существует, это ошибка времени компиляции.

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

Чтобы проиллюстрировать, работает программа печатает

 
Another constructor 
Init 1 
Init 2 
Test constructor 
class Another { 
    Another() { System.out.println("Another constructor"); } 
} 

class Test extends Another { 

    public static void main(String[] args) { new Test(); } 

    { System.out.println("Init 1"); } 

    Test() { System.out.println("Test constructor"); } 

    { System.out.println("Init 2"); } 

} 

Наиболее часто встречается приложение в инициализационные "double brace initialization" idiom,, где определяется анонимный внутренний класс и экземпляр создается и конфигурируется сразу.Вот довольно распространенный пример из свинг программирования:

JButton popupButton = new JButton(new AbstractAction("Popup") { 
    { 
    putValue(Action.SHORT_DESCRIPTION, "Popup a dialog"); 
    } 

    @Override 
    public void actionPerformed(ActionEvent evt) 
    { 
    popup(); 
    } 
}); 

Это может быть полезно, если у вас есть несколько конструкторов, и необходимо выполнить некоторые без параметров инициализации в конструкторе. Это можно было бы включить в блок инициализации.

+0

Этот ответ в значительной степени объясняет порядок, в котором вызываются инициализаторы экземпляров и конструкторы. Благодаря! –

Смежные вопросы