• Home
  • LLMs
  • Python
  • Docker
  • Kubernetes
  • Java
  • Maven
  • All
  • About
Java | Constructeurs
  1. Constructeurs
  2. Règles de déclaration des constructeurs
  3. Informations à savoir sur le code des constrcuteurs
  4. Informations à savoir sur l'exécution des constructeurs

  1. Constructeurs
    Toutes les classes (incluant les classes abstraites) doivent déclarer au moins un constructeur.
    Par défaut, si la classe ne déclare aucun constructeur, le compilateur crée un constructeur sans paramètres (appelé aussi un constructeur par défaut).

    Attention : le compilateur ne créera aucun constructeur si la classe déclare au moins un constructeur.

    Par exemple, pour la classe ClassA le compilateur va créer par défaut le constructeur sans paramètres ClassA() {}:
    class ClassA {
    }
    La classe ClassB n'aura pas de constructeur sans paramètres:
    class ClassB {
        ClassB(int arg1) { }
    }
    Important : les constructeurs ne sont pas héritables ; une sous-classe n'hérite pas les constructeurs de ses superclasses et par conséquent les concepts d'héritage et de redéfinition ne s'appliquent pas aux constructeurs.
  2. Règles de déclaration des constructeurs
    1. Un constructeur ne peut pas retourner une valeur, et par conséquent il ne doit pas déclarer un type de retour.
      On ne peut même pas utiliser le mot clé void.

    2. Un constructeur peut avoir aucun ou plusieurs paramètres.

    3. La déclaration du constructeur peut utiliser n'importe quel modificateur d'accès : public, protected, private, ou l'accès par défaut.

    4. La déclaration du constructeur ne peut pas utiliser les autres modificateurs comme final, static, ...
      public class ClassD {
          final ClassD() { } // compiler error: Illegal modifier for the constructor in type ClassD; only public, protected & private are permitted
      }
    5. Le nom du constructeur doit être le même que celui de la classe où le constructeur est déclaré.

      Attention : Java est sensible à la casse, donc le nom du constructeur et le nom de la classe doivent être exactement pareils.

      class ClassC {
          // Une déclaration légale d'un constructeur
          ClassC() { }
      
          // Le compilateur s'attend à une déclaration de méthode et non à un constructeur
          classc() { } // compiler error: Return type for the method is missing
      
          // Une déclaration légale d'une méthode
          void clASSc() { }
      }
      Il est possible de déclarer une méthode qui a exactement le même nom que celui de la classe ; la différence entre une méthode et un constructeur est :
      • Un constructeur ne déclare pas un type de retour.

      • Un constructeur peut être invoqué par l'operateur new (instanciation).

      • Un constructeur peut être invoqué uniquement à partir de d'autres constructeurs (il ne peut pas être appelé à partir d'une méthode ou d'un bloc d'initialisation).

    6. Il est possible de déclarer plusieurs constructeurs (surcharge des constructeurs) pour la même classe, à condition que les signatures des constructeurs soient différentes (voir les règles de surcharge des méthodes).
      class ClassC {
          ClassC() { }
      
          ClassC(int arg1) { }
      
          ClassC(int arg1, boolean arg2) { }
      }
  3. Informations à savoir sur le code des constrcuteurs
    1. Le compilateur peut ajouter, au début du code du constructeur, un appel au constructeur sans paramètres de la superclasse (super()).

      Attention : le compilateur n'ajoutera aucun appel au constructeur sans paramètres de la superclasse si le code du constructeur contient :
      • un appel explicit (avec le mot clé this) à un autre constructeur de la même classe ;

      • ou un appel explicit (avec le mot clé super) à un constructeur de la superclasse.

      class SuperClass {
          SuperClass() {
              // le compilateur ajoute l'instruction suivante : super();
              System.out.println();
          }
      }
      
      class SubClass extends SuperClass {
          SubClass() {
              // le compilateur ajoute l'instruction suivante : super();
          }
      
          SubClass(boolean arg1) {
              this(); // À cause de l'appel this, le compilateur n'ajoute pas un appel au constructeur sans paramètres de la superclasse
          }
      
          SubClass(int arg1) {
              super(); // À cause de l'appel super, le compilateur n'ajoute pas un appel au constructeur sans paramètres de la superclasse
          }
      }
    2. Si la superclasse ne déclare pas un constructeur sans paramètres, alors il faut ajouter un appel explicite dans le code du constructeur pour invoquer un constructeur de la superclasse qui déclare des paramètres.

      Sinon le compilateur affichera un message d'erreur car, comme vu ci-dessus, le compilateur va essayer d'ajouter un appel au constructeur sans paramètres de la superclasse qui, dans ce cas, ne déclare pas un constructeur sans paramètres !
      class SuperClass1 {
          SuperClass1() { }
      }
      
      class SuperClass2 extends SuperClass1 {
          SuperClass2(int arg1) {
              // OK la superclasse SuperClass1 déclare un constructeur sans paramètres
          }
      }
      
      class SubClass extends SuperClass2 {
          SubClass() { } // compiler error: Implicit super constructor SuperClass2() is undefined. Must explicitly invoke another constructor
      
          SubClass(boolean arg1) {
              this(); // OK : à cause de l'appel this, le compilateur n'ajoute pas un appel au constructeur sans paramètres de la superclasse
          }
      
          SubClass(int arg1) {
              super(arg1); // OK : à cause de l'appel super, le compilateur n'ajoute pas un appel au constructeur sans paramètres de la superclasse
          }
      }
      Pour comprendre l'erreur, voici le code du constructeur comme il est vu par le compilateur :
      class SubClass extends SuperClass2 {
          SubClass() {
              super(); // compiler error: The constructor SuperClass2() is undefined
          }
      
          SubClass(boolean arg1) {
              this();
          }
      
          SubClass(int arg1) {
              super(arg1);
          }
      }
    3. Si les mots clés this et super sont utilisés dans le code du constructeur, il faut qu'ils soient les premières instructions du code, sinon le compilateur générera une erreur.
      class SuperClass2 {
          SuperClass2() { }
      }
      
      class SubClassF extends SuperClass2 {
          SubClassF() {
              System.out.println();
              super(); // compiler error: Constructor call must be the first statement in a constructor
          }
      
          SubClassF(boolean arg1) {
              System.out.println();
              this(); // compiler error: Constructor call must be the first statement in a constructor
          }
      }
    4. Le compilateur générera une erreur si les constructeurs font des appels récursifs.
      class ClassG {
          ClassG() {
              this(true); // compiler error: Recursive constructor invocation ClassG(boolean)
          }
      
          ClassG(boolean arg1) {
              this(); // compiler error: Recursive constructor invocation ClassG()
          }
      }
    5. Il n'est pas possible de passer une variable d'instance (ou un appel à une méthode d'instance) en argument à this(); ou super();.

      Seuls les paramètres du constructeur, les variables de classe, et les méthodes statiques peuvent être passés en argument à this(); ou super();.

      On ne peut pas, dans le code du constructeur, utiliser une variable d'instance ou invoquer une méthode d'instance avant que l'exécution du constructeur parent soit complètement terminé.
      class SuperClass {
          SuperClass() { }
      
          SuperClass(int arg1) { }
      }
      
      class SubClass extends SuperClass {
          int var1 = 1;
          static int var2 = 1;
      
          SubClass() {
              this(var1); // compiler error: Cannot refer to an instance field var1 while explicitly invoking a constructor
          }
      
          SubClass(int arg1) {
              super(var1); // compiler error: Cannot refer to an instance field var1 while explicitly invoking a constructor
          }
      
          SubClass(short arg1) {
              super(arg1); // OK
          }
      
          SubClass(float arg1) {
              this(instanceMethod()); // compiler error: Cannot refer to an instance method while explicitly invoking a constructor
          }
      
          SubClass(double arg1) {
              this(staticMethod()); // OK
          }
      
          SubClass(int arg1, int arg2) {
              this(staticMethod() + arg1 + arg2 + var2); // OK
              var1 = instanceMethod(); // OK
              var2 = staticMethod(); // OK
          }
      
          public Integer instanceMethod() {
              return 0;
          }
      
          public static Integer staticMethod() {
              return 0;
          }
      }
  4. Informations à savoir sur l'exécution des constructeurs
    1. Les constructeurs sont exécutés lors de la création d'une nouvelle instance d'une classe : l'instanciation est faite en utilisant le mot clé new.

      Les arguments passés avec le mot clé new décident quel constructeur sera exécuté.
      class ClassH {
          ClassH() { }
      
          ClassH(int arg1) { }
      }
      
      public class Test1 {
          public static void main(String[] args) {
              new ClassH(); // ClassH() sera exécuté
      
              new ClassH(1); // ClassH(int arg1) sera exécuté
          }
      }
    2. Il est possible d'exécuter plusieurs constructeurs d'une classe lors de son instanciation : le constructeur exécuté en utilisant le mot clé new peut invoquer un autre constructeur de la même classe en utilisant le mot clé this. L'autre constructeur peut à son tour utiliser this pour invoquer un autre constructeur, et ainsi de suite. Voir ci-dessus les détails sur les appels récursifs des constructeurs.

      Les arguments passés avec le mot clé this décident quel constructeur sera exécuté.

      Rappel : L'instruction this (comme c'est le cas avec super) doit être la première ligne du code du constructeur (voir détail ci-dessus).

      class ClassI {
          ClassI() { this(1); } // invocation du constructeur ClassI(int arg1)
      
          ClassI(int arg1) { }
      }
      
      public class Test1 {
          public static void main(String[] args) {
              new ClassI(); // ClassI() sera exécuté
      
              new ClassI(1); // ClassI(int arg1) sera exécuté
          }
      }
    3. L'instanciation garantie qu'au moins un constructeur sera exécuté pour chaque superclasse : le constructeur exécuté avec le mot clé new peut invoquer un autre constructeur de la superclasse en utilisant le mot clé super. Le constructeur de la superclasse peut à son tour utiliser le mot clé super pour invoquer un constructeur de sa superclasse, et ainsi de suite.

      Les arguments passés avec le mot clé super décident quel constructeur de la superclasse sera exécuté.

      Rappel : Le compilateur ajoute par défaut l'instruction super(); au début du code du constructeur, si celui ci ne contient pas un appel explicite au mot clé this ou super.

      class SuperClass {
          SuperClass() { } // le compilateur ajoutera l'instruction "super();" au début du code
      
          SuperClass(int arg1) { } // le compilateur ajoutera l'instruction "super();" au début du code
      }
      
      class SubClass extends SuperClass {
          SubClass() { } // le compilateur ajoutera l'instruction "super();" au début du code
      
          SubClass(int arg1) { super(arg1); } // le constructeur de la superclasse "SuperClass(int arg1)" sera exécuté
      }
© 2025  mtitek