En general, no use bloques de inicializador no estáticos (y tal vez evite también los estáticos).
Sintaxis confusa
Mirando esta pregunta, hay 3 respuestas, pero engañaste a 4 personas con esta sintaxis. ¡Fui uno de ellos y llevo 16 años escribiendo Java! Claramente, la sintaxis es potencialmente propensa a errores. Me mantendría alejado de eso.
Constructores telescópicos
Para cosas realmente simples, puede usar constructores "telescópicos" para evitar esta confusión:
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;
}
}
Patrón de constructor
Si necesita hacerStuff () al final de cada constructor u otra inicialización sofisticada, quizás un patrón de construcción sería lo mejor. Josh Bloch enumera varias razones por las cuales los constructores son una buena idea. Los constructores toman un poco de tiempo para escribir, pero si están escritos correctamente, son un placer usarlos.
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();
Bucles de inicializador estático
Solía usar mucho los inicializadores estáticos , pero ocasionalmente me topé con bucles donde 2 clases dependían de los bloques de inicializadores estáticos que se llamaban antes de que la clase pudiera cargarse por completo. Esto produjo un "error al cargar la clase" o un mensaje de error similarmente vago. Tuve que comparar archivos con la última versión de trabajo conocida en control de código fuente para descubrir cuál era el problema. No es divertido en absoluto.
Inicialización perezosa
Tal vez los inicializadores estáticos son buenos por razones de rendimiento cuando funcionan y no son demasiado confusos. Pero en general, prefiero la inicialización diferida a los inicializadores estáticos en estos días. Está claro lo que hacen, aún no me he encontrado con un error de carga de clase con ellos, y funcionan en más situaciones de inicialización que los bloques de inicializador.
Definición de datos
En lugar de la inicialización estática para construir estructuras de datos (compárese con los ejemplos en las otras respuestas), ahora uso las funciones auxiliares de definición de datos inmutables de 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
Al principio de Java, los bloques de inicialización eran la única forma de hacer algunas cosas, pero ahora son confusos, propensos a errores y, en la mayoría de los casos, han sido reemplazados por mejores alternativas (detalladas anteriormente). Es interesante saber acerca de los bloques de inicializador en caso de que los vea en el código heredado, o que salgan en una prueba, pero si estuviera haciendo una revisión del código y vi uno en el nuevo código, le pediría que justifique por qué ninguno de los las alternativas anteriores eran adecuadas antes de darle el visto bueno a su código.