En général, n'utilisez pas de blocs d'initialisation non statiques (et évitez peut-être aussi les blocs statiques).
Syntaxe déroutante
En regardant cette question, il y a 3 réponses, mais vous avez trompé 4 personnes avec cette syntaxe. J'étais l'un d'eux et j'écris Java depuis 16 ans! De toute évidence, la syntaxe est potentiellement sujette aux erreurs! Je m'en éloignerais.
Constructeurs télescopiques
Pour des choses vraiment simples, vous pouvez utiliser des constructeurs "télescopiques" pour éviter cette confusion:
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;
}
}
Modèle de générateur
Si vous avez besoin de doStuff () à la fin de chaque constructeur ou d'une autre initialisation sophistiquée, un modèle de générateur serait peut-être préférable. Josh Bloch énumère plusieurs raisons pour lesquelles les constructeurs sont une bonne idée. Les constructeurs prennent un peu de temps à écrire, mais correctement écrits, ils sont une joie à utiliser.
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();
Boucles d'initialisation statique
J'utilisais beaucoup les initialiseurs statiques , mais je rencontrais parfois des boucles où 2 classes dépendaient des blocs d'initialisation statiques de l'autre avant que la classe puisse être entièrement chargée. Cela a produit un "échec de chargement de classe" ou un message d'erreur tout aussi vague. J'ai dû comparer des fichiers avec la dernière version de travail connue dans le contrôle de code source afin de comprendre quel était le problème. Pas du tout amusant.
Initialisation paresseuse
Peut-être que les initialiseurs statiques sont bons pour des raisons de performances lorsqu'ils fonctionnent et ne sont pas trop déroutants. Mais en général, je préfère l' initialisation paresseuse aux initialiseurs statiques de nos jours. Il est clair ce qu'ils font, je n'ai pas encore rencontré de bogue de chargement de classe avec eux, et ils fonctionnent dans plus de situations d'initialisation que les blocs d'initialisation.
Définition des données
Au lieu de l'initialisation statique pour la construction de structures de données, (comparer avec des exemples dans les autres réponses), j'utilise maintenant les fonctions d'assistance de définition de données immuables 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
Au début de Java, les blocs d'initialisation étaient le seul moyen de faire certaines choses, mais maintenant ils sont déroutants, sujets aux erreurs et, dans la plupart des cas, ont été remplacés par de meilleures alternatives (détaillées ci-dessus). Il est intéressant de connaître les blocs d'initialisation au cas où vous les verriez dans le code hérité, ou s'ils reviennent sur un test, mais si je faisais une revue de code et que j'en voyais un dans du nouveau code, je vous demanderais de justifier pourquoi aucun des Les alternatives ci-dessus étaient appropriées avant de donner votre accord.