11
votes

Que se passe-t-il lorsque les sous-classes ne définissent pas un constructeur en Java?

J'ai quelques cas où je me demande. Tout d'abord, si vous n'avez pas de constructeur: xxx pré>

lorsque je fais nouveaux nocons () code>, le constructeur par défaut est appelé. Qu'est-ce que ça fait exactement? Est-ce qu'il définit x code> sur 0 ou cela se produit ailleurs? P>

Et si j'ai cette situation: p> xxx pré>

quoi arrive quand j'appelle nouveau nocons2 () code>? Le constructeur par défaut code> est-il appelé NOCONS code>, puis constructeur de nocons2 code>? Est-ce qu'ils définissent chacun les champs respectifs x code> et y code> sur 0? P>

Qu'en est-il de cette version: p>

class Cons { int x; public Cons() {} }
class NoCons2 extends Cons { int y;  }


0 commentaires

4 Réponses :


14
votes

Lorsqu'une classe Java n'a pas de constructeur défini explicitement un constructeur de défaut de no-args public est ajouté, de sorte que:

new NoCons2();


0 commentaires

0
votes

Cletus a répondu au plus grand des questions. La réponse à l'autre est que les variables de membre en Java sont initialisées à 0, null ou false (selon le type).


0 commentaires

1
votes

Vous voulez vous référer au Spécification de la langue Java Section 12.5 Création de nouvelles instances de classe pour obtenir les règles officielles de la création d'objets. La section correspondante est la suivante:

juste avant la référence à l'objet nouvellement créé est renvoyé comme résultat, le constructeur indiqué est traité pour initialiser le nouvel objet en utilisant la procédure suivante: p>

  1. Attribuez les arguments du constructeur aux variables de paramètres nouvellement créées pour cette invocation du constructeur. LI>
  2. Si ce constructeur commence par une invocation de constructeur explicite d'un autre constructeur dans la même classe (en utilisant ceci), puis évaluez les arguments et traitez de ce que l'invocation du constructeur utilise récursivement ces cinq étapes. Si cette invocation du constructeur se termine brusquement, cette procédure complète brusquement la même raison; Sinon, continuez avec l'étape 5. Li>
  3. Ce constructeur ne commence pas par une invocation de constructeur explicite d'un autre constructeur dans la même classe (en l'utilisant). Si ce constructeur est pour une classe autre que l'objet, ce constructeur commencera par une invocation explicite ou implicite d'un constructeur de superclasse (en utilisant Super). Évaluez les arguments et procédez à l'invocation du constructeur de superclasse à l'aide de ces mêmes cinq étapes. Si cette invocation du constructeur est terminée brusquement, cette procédure complète brusquement la même raison. Sinon, continuez avec l'étape 4. Li>
  4. Exécutez les initialisateurs d'instance et les initialisateurs de variable d'instance pour cette classe, attribuant les valeurs d'initialistes variables d'instance aux variables d'instance correspondantes, dans l'ordre de gauche à droite dans lequel ils apparaissent textuellement dans le code source de la classe. Si l'exécution de l'un de ces initialiseurs entraîne une exception, aucune autre initialistes n'est traitée et cette procédure complète brusquement la même exception. Sinon, passez à l'étape 5. (Dans certaines implémentations précoces, le compilateur a mal omis le code pour initialiser un champ si l'expression d'initialisateur de champ était une expression constante dont la valeur était égale à la valeur d'initialisation par défaut pour son type.) Li>
  5. Exécutez le reste du corps de ce constructeur. Si cette exécution complète brusquement, cette procédure complète brusquement la même raison. Sinon, cette procédure se termine normalement. Li> ol> BlockQuote>

    Donc, dans vos exemples, lorsque aucun constructeur n'est fourni dans votre définition de classe, le par défaut est inséré pour vous. Lorsque vous écrivez P>

    new NoCons2();
    


0 commentaires

0
votes

Voici essentiellement ce qui se passe quand « nouveau » est appelé:

  • la mémoire est allouée (assez pour tenir tous les membres de données de la classe, et toutes les classes de parents, ainsi que des informations d'ordre administratif) li>
  • la mémoire allouée est mise à zéro (ce qui signifie 0, 0,0, false, null en fonction dans le type) li>
  • le constructeur est appelé pour la classe qui est après « nouveau » est appelé. Li>
  • plus les choses (à venir après la partie suivante) li> Ul>

    Si vous ne fournissez pas de constructeur le compilateur effectue les opérations suivantes: p>

    • crée un constructeur sans argument li>
    • le constructeur créé a le même accès que la classe (si public ou package) li>
    • super () est appelée. Li> Ul>

      Ainsi, lorsque le constructeur de la classe après la « nouvelle » est appelée la première chose qu'il fait est appel « super () » qui appelle le constructeur parent. Cela arrive tout le chemin jusqu'à java.lang.Object. P>

      Avant que le corps du constructeur est exécuté la machine virtuelle effectue les opérations suivantes: p>

      • les variables d'instance qui sont les valeurs affectées leur sont données li>
      • puis l'instance initialiseur bloc, le cas échéant est exécuté. Li> Ul>

        Le code suivant montre tous ceci: p>

        public class Main
        {
            private Main()
            {
            }
        
            public static void main(final String[] args)
            {
                final Foo fooA;
                final Foo fooB;
        
                fooA = new Foo(7);
                System.out.println("---------------------");
                fooB = new Foo(42);
            }
        }
        
        class Bar
        {
            protected int valueA = getValue("valueA", 1);
            protected int valueB;
        
            static
            {
                System.out.println("static block for Bar happens only one time");
            }
        
            {
                System.out.println("instance block for Bar happens one time for each new Bar");
                System.out.println("valueA = " + valueA);
                System.out.println("valueB = " + valueB);
            }
        
            Bar()
            {
                super();  // compiler adds this - you would not type it in
                System.out.println("running Bar()");
                System.out.println("valueA = " + valueA);
                System.out.println("valueB = " + valueB);
                valueB = getValue("valueB", 2);
            }
        
            protected static int getValue(final String name, final int val)
            {
                System.out.println("setting " + name + " to " + val);
                return (val);
            }
        }
        
        class Foo
            extends Bar
        {
            protected int valueC = getValue("valueC", 1);
            protected int valueD;
        
            static
            {
                System.out.println("static block for Foo happens only one time");
            }
        
            {
                System.out.println("instance block for Foo happens one time for each new Foo");
                System.out.println("valueC = " + valueC);
                System.out.println("valueD = " + valueD);
            }
        
            Foo(final int val)
            {
                super();  // compiler adds this - you would not type it in
                System.out.println("running Foo(int)");
                System.out.println("valueC = " + valueC);
                System.out.println("valueD = " + valueD);
                valueD = getValue("valueD", val);
            }
        }
        


0 commentaires