Dois-je initialiser une variable dans un constructeur ou un constructeur externe

Lorsque j’utilise Java sur la base de mes connaissances C ++, j’adore initialiser les variables de la manière suivante.

public class ME { private int i; public ME() { this.i = 100; } } 

Après quelque temps, je change l’habitude de

 public class ME { private int i = 100; public ME() { } } 

Je suis tombé sur d’autres codes source, certains utilisent la 1ère convention, d’autres utilisent la 2ème convention.

Puis-je savoir quelle convention vous recommandez tous et pourquoi?

Je trouve le second style (déclaration + initialisation en un seul coup) supérieur. Les raisons:

  • Cela montre clairement comment la variable est initialisée. Généralement, lorsque vous lisez un programme et que vous rencontrez une variable, vous allez d’abord consulter sa déclaration (souvent automatique dans les EDI). Avec le style 2, vous voyez immédiatement la valeur par défaut. Avec le style 1, vous devez également examiner le constructeur.
  • Si vous avez plusieurs constructeurs, vous n’avez pas à répéter les initialisations (et vous ne pouvez pas les oublier).

Bien sûr, si la valeur d’initialisation est différente dans différents constructeurs (ou même calculée dans le constructeur), vous devez le faire dans le constructeur.

J’ai tendance à utiliser le second pour éviter un constructeur compliqué (ou inutile), et je ne considère pas cela comme une initialisation (même si c’est une initialisation), mais plutôt comme une valeur par défaut.

Par exemple, dans votre second extrait, vous pouvez supprimer le constructeur et avoir un code plus clair.

J’ai l’habitude (presque) d’initialiser presque toujours dans le constructeur pour deux raisons, une à mon avis qui ajoute à la lisibilité (plus propre), et deux il y a plus de contrôle logique dans le constructeur que dans une ligne. Même si initialement la variable d’instance ne nécessite pas de logique, l’avoir dans le constructeur donne plus de flexibilité pour append de la logique dans le futur si nécessaire.

En ce qui concerne l’inquiétude mentionnée ci-dessus à propos de plusieurs constructeurs, cela se résout facilement en ayant un constructeur no-arg qui initialise toutes les variables d’instance initiées de la même manière pour chaque constructeur. Chaque constructeur appelle this () sur la première ligne. Cela résout vos problèmes de redondance.

Le seul problème que je vois avec la première méthode est si vous envisagez d’append plus de constructeurs. Ensuite, vous répéterez le code et la maintenabilité en souffrira.

Si vous initialisez dans le haut ou dans le constructeur, cela ne fait pas beaucoup de différence. Mais dans certains cas, l’initialisation dans le constructeur est logique.

 class Ssortingng { char[] arr/*=char [20]*/; //Here initializing char[] over here will not make sense. Ssortingng() { this.arr=new char[0]; } Ssortingng(char[] arr) { this.arr=arr; } } 

Donc, en fonction de la situation, vous devrez parfois initialiser dans le haut et parfois dans un constructeur.

FYI autre option pour l’initialisation sans utiliser de constructeur:

 class Foo { int i; static int k; //instance initializer block { //run's every time a new object is created i=20; } //static initializer block static{ //run's only one time when the class is loaded k=18; } } 

Je recommande d’initialiser les variables dans les constructeurs. C’est pourquoi ils existent: pour vous assurer que vos objects sont construits (initialisés) correctement.

De toute façon, ça va marcher, et c’est une question de style, mais je préfère les constructeurs pour l’initialisation des membres.

Une chose, quelle que soit la façon dont vous initialisez le champ, l’utilisation du qualificatif final , si possible, assurera la visibilité de la valeur du champ dans un environnement multithread.

Je pense que les deux sont corrects sur le plan de la programmation,

Mais je pense que votre première option est plus correcte de manière orientée object, car dans le constructeur, c’est quand l’object est créé, et c’est quand la variable doit être initialisée.

Je pense que c’est la convention “par le livre”, mais elle est ouverte à la discussion.

Wikipédia

Les deux options peuvent être correctes en fonction de votre situation.

Un exemple très simple serait: Si vous avez plusieurs constructeurs qui initialisent tous la variable de la même manière (int x = 2 pour chacun d’eux). Il est judicieux d’initialiser la variable à la déclaration pour éviter la redondance.

Il est également logique de considérer les variables finales dans une telle situation. Si vous savez quelle valeur une variable finale aura à la déclaration, il est judicieux de l’initialiser en dehors des constructeurs. Toutefois, si vous souhaitez que les utilisateurs de votre classe initialisent la variable finale via un constructeur, retardez l’initialisation jusqu’au constructeur.

Cela peut dépendre de ce que vous initialisez, par exemple, vous ne pouvez pas simplement utiliser l’initialisation du champ si une exception vérifiée est impliquée. Par exemple, les éléments suivants:

 public class Foo { FileInputStream fis = new FileInputStream("/tmp"); // throws FileNotFoundException } 

Entraînera une erreur de compilation sauf si vous incluez également un constructeur déclarant cette exception vérifiée ou étendez une super-classe, par exemple:

 public Foo() throws FileNotFoundException {} 

Je dirais que cela dépend du défaut . Par exemple

 public Bar { ArrayList foos; } 

Je ferais une new ArrayList dehors du constructeur, si je suppose toujours que foos ne peut pas être nul. Si Bar est un object valide, ne se souciant pas si foos est nul ou non, je le placerais dans le constructeur.

Vous pourriez ne pas être d’accord et dire que c’est le travail des constructeurs de placer l’object dans un état valide. Cependant, si clairement tous les constructeurs doivent faire exactement la même chose (initialiser foos ), pourquoi dupliquer ce code?