Em geral, não use blocos inicializadores não estáticos (e talvez evite também estáticos).
Sintaxe Confusa
Olhando para esta pergunta, existem 3 respostas, mas você enganou 4 pessoas com esta sintaxe. Eu era um deles e escrevo Java há 16 anos! Claramente, a sintaxe é potencialmente propensa a erros! Eu ficaria longe disso.
Construtores telescópicos
Para coisas realmente simples, você pode usar construtores "telescópicos" para evitar essa confusão:
public class Test {
private String something;
// Default constructor does some things
public Test() { doStuff(); }
// Other constructors call the default constructor
public Test(String s) {
this(); // Call default constructor
something = s;
}
}
Padrão do Construtor
Se você precisar fazerStuff () no final de cada construtor ou outra inicialização sofisticada, talvez um padrão de construtor seja o melhor. Josh Bloch lista várias razões pelas quais os construtores são uma boa idéia. Os construtores demoram um pouco para escrever, mas adequadamente escritos, eles são uma alegria de usar.
public class Test {
// Value can be final (immutable)
private final String something;
// Private constructor.
private Test(String s) { something = s; }
// Static method to get a builder
public static Builder builder() { return new Builder(); }
// builder class accumulates values until a valid Test object can be created.
private static class Builder {
private String tempSomething;
public Builder something(String s) {
tempSomething = s;
return this;
}
// This is our factory method for a Test class.
public Test build() {
Test t = new Test(tempSomething);
// Here we do your extra initialization after the
// Test class has been created.
doStuff();
// Return a valid, potentially immutable Test object.
return t;
}
}
}
// Now you can call:
Test t = Test.builder()
.setString("Utini!")
.build();
Loops de Inicializador Estático
Eu costumava usar muito inicializadores estáticos , mas ocasionalmente encontrava loops em que duas classes dependiam dos blocos de inicializadores estáticos um do outro serem chamados antes que a classe pudesse ser totalmente carregada. Isso produziu uma mensagem de erro "falha ao carregar a classe" ou uma vaga igualmente semelhante. Eu tive que comparar arquivos com a última versão de trabalho conhecida no controle de origem para descobrir qual era o problema. Nada divertido.
Inicialização lenta
Talvez os inicializadores estáticos sejam bons por razões de desempenho quando funcionam e não são muito confusos. Mas, em geral, estou preferindo a inicialização lenta a inicializadores estáticos atualmente. Está claro o que eles fazem, ainda não encontrei um bug de carregamento de classe e eles funcionam em mais situações de inicialização do que os blocos de inicialização.
Definição de dados
Em vez de inicialização estática para a construção de estruturas de dados (compare com os exemplos nas outras respostas), agora uso as funções auxiliares de definição de dados imutáveis do Paguro :
private ImMap<String,String> days =
map(tup("mon", "monday"),
tup("tue", "tuesday"),
tup("wed", "wednesday"),
tup("thu", "thursday"),
tup("fri", "friday"),
tup("sat", "saturday"),
tup("sun", "sunday"));
Conculsion
No início do Java, os blocos inicializadores eram a única maneira de fazer algumas coisas, mas agora eles são confusos, propensos a erros e, na maioria dos casos, foram substituídos por alternativas melhores (detalhadas acima). É interessante saber sobre os blocos de inicializadores, caso você os veja em código legado ou eles surjam em um teste, mas se eu estivesse revisando o código e vi um no novo código, pediria que justificasse por que nenhum dos as alternativas acima foram adequadas antes de dar o polegar para cima ao código.