99 votes

Dans quel ordre les blocs statiques et les blocs d'initialisation s'exécutent-ils lors de l'utilisation de l'héritage ?

J'ai deux classes Parent et Child

public class Parent {    
    public Parent() {
        System.out.println("Constructeur Parent");
    }    
    static {
        System.out.println("Bloc statique Parent");    
    }    
    {
        System.out.println("Bloc d'initialisation Parent");
    }
}

public class Child extends Parent {    
    {
        System.out.println("Bloc d'initialisation enfant");
    }
    static {
        System.out.println("Bloc statique enfant");
    }

    public Child() {
        System.out.println("Constructeur enfant");
    }    
    public static void main(String[] args) {
        new Child();    
    }
}

La sortie du code ci-dessus sera

Bloc statique Parent
Bloc statique enfant
Bloc d'initialisation Parent
Constructeur Parent
Bloc d'initialisation enfant
Constructeur enfant

Pourquoi Java exécute-t-il le code dans cet ordre? Quelles sont les règles qui déterminent l'ordre d'exécution?

78voto

Supuhstar Points 2310

Je apprends visuellement, donc voici une représentation visuelle de l'ordre, sous la forme d'un SSCCE:

public class Example {

    static {
        step(1);
    }

    public static int step_2 = step(2);
    public int step_8 = step(8);

    public Example(int unused) {
        super();
        step(10);
    }

    {
        step(9);
    }

    // Juste pour démonstration:
    public static int step(int step) {
        System.out.println("Étape " + step);
        return step;
    }
}

public class ExampleSubclass extends Example {

    {
        step(11);
    }

    public static int step_3 = step(3);
    public int step_12 = step(12);

    static {
        step(4);
    }

    public ExampleSubclass(int unused) {
        super(step(7));
        step(13);
    }

    public static void main(String[] args) {
        step(5);
        new ExampleSubclass(step(6));
        step(14);
    }
}

Ceci affiche:

Étape 1
Étape 2
Étape 3
Étape 4
Étape 5
Étape 6
Étape 7
Étape 8
Étape 9
Étape 10
Étape 11
Étape 12
Étape 13
Étape 14

Gardez à l'esprit que l'ordre des parties static est important; regardez la différence entre l'ordre des éléments static de Example et de ExampleSubclass.

Remarquez également que le bloc d'initialisation d'instance est toujours exécuté immédiatement après l'appel à super() dans le constructeur (même si cet appel est implicite/omis), peu importe l'ordre. Cependant, l'ordre est important entre un bloc d'initialisation et un initialiseur de champ.

61voto

Petr Mensik Points 8588

Il existe plusieurs règles en jeu

  • Les blocs statiques sont toujours exécutés avant que l'objet ne soit créé, c'est pourquoi vous voyez des messages d'impression à la fois des blocs statiques parent et enfant
  • Maintenant, lorsque vous appelez le constructeur de la sous-classe (enfant), ce constructeur appelle implicitement super(); avant d'exécuter son propre constructeur. Le bloc d'initialisation entre en jeu même avant l'appel du constructeur, c'est pourquoi il est appelé en premier. Maintenant votre parent est créé et le programme peut continuer à créer la classe enfant qui subira le même processus.

Explications:

  1. Le bloc statique du parent est exécuté en premier car il est chargé en premier et les blocs statiques sont appelés lorsque la classe est chargée.

9voto

Raúl Points 211

Premièrement - exécutez uniquement la classe enfant (commentez la clause d'extension) pour voir le flux simple.

Deuxièmement - allez sur Bloc statique vs. bloc d'initialisation en Java? et lisez la réponse acceptée là-bas.

Modifier:

  1. L'exécution se fait de manière SIC - Statique, Initialisateur (non statique) & Constructeur.
  2. Les initialisateurs (non statiques) sont copiés dans chaque constructeur - AU SOMMET! (d'où les lignes 3/4/5/6).
  3. Avant qu'une classe ne soit initialisée, sa superclasse directe doit être initialisée - http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4 (d'où le bloc statique parent apparaît en premier).

9voto

  • Les blocs d'initialisation statiques sont exécutés au moment du chargement de la classe.
  • Dans la hiérarchie des classes, l'ordre d'exécution des blocs d'initialisation statiques commencera par la classe de niveau supérieur.
  • Dans une classe, l'ordre d'exécution du bloc statique est de haut en bas.
  • La règle ci-dessus s'applique indépendamment de l'endroit où se trouve le bloc statique dans la classe.

(Dans votre code, les blocs statiques parent seront exécutés en premier, puis les blocs statiques de la classe enfant.)

  • Les blocs d'initialisation d'instance seront exécutés après l'appel au super(); dans le constructeur.
    • super(); est toujours la toute première déclaration dans un constructeur par défaut.

Dans votre code lorsque vous créez un objet Enfant :

  • Le constructeur par défaut de la classe Enfant est exécuté.
  • Il appellera le constructeur super();
  • Ensuite, le constructeur de la super classe est exécuté.
  • La classe Parent exécutera son appel super();
  • Après quoi, les blocs d'initialisation d'instance dans la classe Parent sont exécutés. (De haut en bas).
  • Ensuite, le code à l'intérieur du constructeur est exécuté (s'il y en a).
  • Ensuite, il reviendra à la classe Enfant et exécutera les blocs d'initialisation d'instance de la classe Enfant.
  • Enfin, le code dans le constructeur de la classe Enfant est exécuté (s'il existe).

5voto

rohan kamat Points 291

Le bloc statique en java est exécuté avant la méthode principale. Si nous déclarons un bloc statique dans une classe java, il est exécuté lorsque la classe se charge. Cela initialise les variables statiques. Il est principalement utilisé dans JDBC. Le bloc statique en java est exécuté à chaque fois qu'une classe se charge. C'est aussi appelé bloc d'initialisation statique. Le bloc statique en java s'initialise lorsque la classe se charge en mémoire, c'est-à-dire lorsque la JVM lit le bytecode. L'initialisation peut être n'importe quoi; cela peut être une initialisation de variable ou autre chose qui devrait être partagée par tous les objets de cette classe. Le bloc statique est un bloc de code normal entre accolades { } et précédé du mot-clé static.

donc le bloc statique est exécuté en premier.

Blocs d'initialisation d'instance : S'exécute à chaque fois qu'une instance de la classe est créée.

donc le prochain bloc d'initialisation est exécuté lorsque l'instance de la classe est créée.

puis le constructeur est exécuté

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