Comment appeler un constructeur depuis un autre constructeur en Java : analyse sous le capot

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Comment appeler un constructeur depuis un autre en Java : détails non évidents qui changeront votre code



Avez-vous déjà écrit une classe Java avec 5 à 6 constructeurs et eu l'impression de vous noyer dans la duplication de code ? Ou, au contraire, avez-vous regardé du code où apparaissait un mystérieux this(name, 0, true) en vous demandant : « Quelle est cette magie ? ».



La question « How do I call one constructor from another in Java? » est l'une des plus populaires sur Stack Overflow (des milliers de vues et des centaines de réponses). Et ce n'est pas sans raison. Une opération apparemment simple — l'appel d'un constructeur — cache de nombreuses nuances qui affectent les performances, la lisibilité et même la correction du programme.



Dans cet article, nous ne nous contenterons pas de montrer la syntaxe. Nous regarderons sous le capot de la JVM, analyserons comment le compilateur traite ces appels, et donnerons des conseils pratiques utiles aussi bien au débutant qu'au développeur expérimenté.



Pourquoi appeler un constructeur depuis un autre ? Le problème de la duplication



Imaginez que vous écrivez une classe User avec des champs obligatoires (nom, email) et optionnels (âge, téléphone). Vous souhaitez offrir de la flexibilité aux utilisateurs de votre API : créer un objet avec un minimum de données ou avec tous les détails.



Mauvaise approche (sans appel de constructeur) :

public class User {    private String name;    private String email;    private int age;    private String phone;

public User(String name, String email) { this.name = name; this.email = email; this.age = 0; // valeur par défaut this.phone = null; // valeur par défaut }

public User(String name, String email, int age) { this.name = name; this.email = email; this.age = age; this.phone = null; // encore de la duplication }

public User(String name, String email, int age, String phone) { this.name = name; this.email = email; this.age = age; this.phone = phone; }}


Ici, nous assignons name et email trois fois. Si un nouveau champ est ajouté, il faudra modifier tous les constructeurs. Cela viole le principe DRY (Don't Repeat Yourself) et augmente le risque d'erreurs.



Bonne approche (avec appel de constructeur via this()) :

public class User {    private String name;    private String email;    private int age;    private String phone;

public User(String name, String email) { this(name, email, 0, null); // délégation au constructeur le plus complet }

public User(String name, String email, int age) { this(name, email, age, null); // encore une délégation }

public User(String name, String email, int age, String phone) { this.name = name; this.email = email; this.age = age; this.phone = phone; }}


Maintenant, toute la logique d'initialisation se trouve dans un seul constructeur. Les autres lui délèguent simplement le travail en passant des valeurs par défaut. C'est concis, facile à maintenir et il y a moins de risques d'oublier un champ.



Syntaxe d'appel d'un constructeur : this() et super()



En Java, il existe deux mots-clés pour appeler des constructeurs :

  • this(paramètres) — appelle un autre constructeur de la même classe.
  • super(paramètres) — appelle un constructeur de la classe parente.


Règle cruciale : l'appel à this() ou super() doit être la première instruction dans le constructeur. Pourquoi ? Nous y reviendrons.



Exemple avec héritage :

class Animal {    private String species;

public Animal(String species) { this.species = species; System.out.println("Animal constructor: " + species);

Blogs

Book Recommendations