En general, no use bloques de inicialización no estáticos (y quizás evite los estáticos también).
Sintaxis confusa
Mirando esta pregunta, hay 3 respuestas, sin embargo, engañó 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 ello.
Constructores telescópicos
Para cosas realmente simples, puedes 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 del generador
Si necesita hacer cosas () al final de cada constructor u otra inicialización sofisticada, tal vez lo mejor sería un patrón de construcción. Josh Bloch enumera varias razones por las que los constructores son una buena idea. Los constructores toman un poco de tiempo para escribir, pero correctamente escritos, es un placer utilizarlos.
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 inicialización estáticos
Solía usar mucho los inicializadores estáticos , pero ocasionalmente me topaba con bucles en los que 2 clases dependían de los bloques de inicialización 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 inicialización perezosa a los inicializadores estáticos en estos días. Está claro lo que hacen, todavía no me he encontrado con un error de carga de clase, y funcionan en más situaciones de inicialización que los bloques de inicialización.
Definición de datos
En lugar de la inicialización estática para construir estructuras de datos (compare con los ejemplos de las otras respuestas), ahora uso las funciones de ayuda para la 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"));
Conculsión
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 inicialización en caso de que los vea en el código heredado, o que aparezcan en una prueba, pero si estuviera haciendo una revisión del código y viera uno en el código nuevo, le pediría que justifique por qué ninguno de los Las alternativas anteriores eran adecuadas antes de dar el visto bueno a su código.