2013-08-07 3 views
6

В моих проектах был разработчик, которому понравился блок статической инициализации .Какова альтернатива блоку нестатической инициализации?

Что такое альтернатива к этому и то, что является недостатком этой альтернативы? Я бы предположил: инициализировать значения в конструкторе ?

Почему мы должны использовать блок без инициализации? Насколько я понял, «блок инициализации» используется для установки значений при создании экземпляра класса. Является ли тогда конструктором недостаточно?

public class BlockTest { 
    String test = new String(); 

    //Non-static initialization block 
    { 
     test = "testString"; 
    } 
} 

Этот блок меня смущает и ведет к снижению удобочитаемости. Спасибо за ваш ответ!

+0

конструктора .. – Ankit

ответ

10

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

Одна альтернатива инициализируется при объявлении:

public class BlockTest { 
    String test = "testString"; 
} 

Другой в конструкторе:

public class BlockTest { 
    String test; 
    public BlockTest() { 
     test = "testString"; 
    } 
} 

Таковы две основные, общие параметры.

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

new BaseClass() { 
    List<String> strings = new ArrayList<String>(); 
    { 
     strings.add("first"); 
     strings.add("second"); 
    } 
} 

второй является для общей инициализации, которые должны произойти перед каждым конструктором:

public class MediocreExample { 
    List<String> strings = new ArrayList<String>(); 
    { 
     strings.add("first"); 
     strings.add("second"); 
    } 
    public MediocreExample() { 
     ... 
    } 
    public MediocreExample (int parameter) { 
     ... 
    } 
}   

Однако в обоих случаях есть альтернативы которые не используют блок инициализации:

new BaseClass() { 
    List<String> strings = createInitialList(); 
    private List<String> createInitialList() { 
     List<String> a = new ArrayList<String>(); 
     a.add("first"); 
     a.add("second"); 
     return a; 
    } 
} 

И:

public class MediocreExample { 
    List<String> strings; 
    private void initialize() { 
     strings = new List<String>(); 
     strings.add("first"); 
     strings.add("second"); 
    } 
    public MediocreExample() { 
     initialize(); 
     ... 
    } 
    public MediocreExample (int parameter) { 
     initialize(); 
     ... 
    } 
}   

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

+0

+1 для покрытия случаев, когда речь идет об альтернативе. – kiheru

+0

Это правильно, что нет смысла инициализировать строку там, но это было только для примера;;) –

2

блок инициализации не имеет альтернативы, на самом деле это альтернатива конструктору.

public TestClass { 
     TestClass() { 

     } 
    } 

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

new MyClass(){ 
    //its an anonymous class, you can't use constructor here 
     { 
     } 
    } 

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

public TestClass { 
    String test = "value"; 
} 

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

public TestClass { 
     String test = "value"; 
     test = test + " not found"//compiler error 
     { 
     test = test + " not found" // valid 
     } 
    } 
+0

можно инициализировать поля, где они заявлены, если вы просто присвоения значений. –

+1

@JasonC см. Мое редактирование – Ankit

+0

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

6

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

class Test1 { 
    int x = 1; 
    { 
     x = 2; 
    } 
    Test1() { 
     x = 3; 
    } 
} 

компилируется в то же bytecoode как это

class Test1 { 
    int x; 
    Test1() { 
     x = 1; 
     x = 2; 
     x = 3; 
    } 
} 
+0

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

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