87 votes

En quoi un initialisateur d'instance est-il différent d'un constructeur ?

En d'autres termes, pourquoi auriez-vous besoin d'un initialisateur d'instance ? Quelle différence ou quel avantage y a-t-il à écrire un initialisateur d'instance plutôt qu'un constructeur ?

2 votes

Les initialisateurs d'instance sont assez rares (sauf si vous tombez sur le code de quelqu'un qui aime l'idiome de la double accolade).

112voto

javamonkey79 Points 6807

Ceci semble bien l'expliquer :

Les initialisateurs d'instance sont une alternative utile aux variables d'instance. dans tous les cas :

  • le code de l'initialisateur doit attraper les exceptions, ou

  • effectuer des calculs fantaisistes qui ne peuvent pas être exprimés avec un initialisateur de variable d'instance. Vous pouvez, bien sûr, toujours écrire ce code dans des constructeurs.

Mais dans une classe comportant plusieurs constructeurs, vous devriez répéter le code dans chaque constructeur. Avec un initialisateur d'instance, vous vous pouvez écrire le code une seule fois, et il sera exécuté quel que soit le constructeur constructeur est utilisé pour créer l'objet. Les initialisateurs d'instance sont également utiles dans les classes internes anonymes, qui ne peuvent déclarer aucun constructeur. constructeurs du tout.

De : JavaWorld Initialisation d'objets en Java .

19 votes

D'autre part, vous pouvez écrire du code une fois dans un constructeur et l'appeler à partir de tous les autres constructeurs. Mais les classes internes anonymes sont un bon point.

11 votes

Vous pouvez l'appeler à partir d'autres constructeurs, mais vous répétez alors l'appel. Si vous ajoutez un nouveau constructeur, vous devez vous rappeler d'ajouter l'appel à celui-ci. Ce n'est pas le cas avec un initialisateur d'instance.

6 votes

@talonx, je suis d'accord avec votre argument sur l'oubli, mais utiliser le comportement par défaut est tout aussi dangereux. Lorsqu'un supporter lit un constructeur dans un code hérité, il ne se souvient pas toujours de vérifier les initialisateurs d'instance possibles. Alors qu'un init() explicitement utilisé se fera remarquer.

22voto

ykaganovich Points 8497

En termes de cycle de vie des objets, il n'y a pas de différence. Les deux sont invoqués au moment de la construction, et logiquement le bloc initialisateur peut être considéré comme faisant partie de la construction.

D'un point de vue sémantique, un initialisateur est un outil intéressant à posséder pour plusieurs raisons :

l'initialisateur peut améliorer la lisibilité du code en conservant la logique d'initialisation à côté de la variable à initialiser :

   public class Universe {
       public int theAnswer;
       {
         int SIX = 6;
         int NINE = 7;
         theAnswer = SIX * NINE;
       }

       // a bunch of other vars
   }

vs

   public class Universe {
       public int theAnswer;

       // a bunch of other vars

       public Universe() {
         int SIX = 6;
         int NINE = 7;
         theAnswer = SIX * NINE;

         // other constructor logic
       }
   }

Les initialisateurs sont invoqués sans tenir compte quel que soit le constructeur utilisé.

Les initialisateurs peuvent être utilisés dans des anonymes, où les constructeurs ne le peuvent pas.

3 votes

Ce que vous avez là est techniquement un "initialisateur de variable d'instance" et non un "initialisateur d'instance" (un bloc directement imbriqué dans une classe). Voir JLS 3e section 8.6.

0 votes

Le bloc initialisateur d'instance n'a pas de nom, comme indiqué. ici . N'est-ce pas ? Vous avez marqué votre code d'initialisation d'instance avec le nom theAnswer . Est-ce correct ? ou j'ai raté quelque chose.

1 votes

@RBT theAnswer est une variable d'instance déclarée. Elle est initialisée dans un bloc initialisateur anonyme. Notez le point-virgule après la déclaration de la variable.

12voto

Rahul Garg Points 1687

Lorsque vous avez plusieurs constructeurs et que vous voulez qu'un code commun soit exécuté pour chaque constructeur, vous pouvez utiliser l'initialisateur d'instance, qui est appelé pour tous les constructeurs.

4voto

CPerkins Points 5209

J'éviterais l'idiome de l'initialisateur d'instance en général - le seul avantage réel qu'il offre par rapport aux initialisateurs de variables est la gestion des exceptions.

Et comme une méthode init (appelable depuis le constructeur) peut également gérer les exceptions et centraliser le code de configuration du constructeur, mais a l'avantage de pouvoir opérer sur les valeurs des paramètres du constructeur, je dirais que l'initialisateur d'instance est redondant, et donc à éviter.

1 votes

Vous devriez appeler manuellement la méthode init dans TOUS vos constructeurs.

2 votes

@Alex Bon point, mais comme la plupart des classes avec plusieurs constructeurs ont une logique commune, elles ont tendance à s'appeler les unes les autres de toute façon. Du moins dans la plupart de mes classes.

4voto

padippist Points 537

Le site Le véritable avantage des initialisateurs d'instance par rapport aux constructeurs apparaît lorsque nous utilisons une classe interne anonyme. .

Les classes internes anonymes ne peuvent pas avoir de constructeur. (puisqu'ils sont anonymes) , donc ils sont un ajustement assez naturel pour initialisateurs d'instance .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X