web-dev-qa-db-fra.com

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 enfant

public class Parent {    
    public Parent() {
        System.out.println("Parent Constructor");
    }    
    static {
        System.out.println("Parent static block");    
    }    
    {
        System.out.println("Parent initialisation  block");
    }
}

public class Child extends Parent {    
    {
        System.out.println("Child initialisation block");
    }
    static {
        System.out.println("Child static block");
    }

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

La sortie du code ci-dessus sera

Parent static block
Child static block
Parent initialization  block
Parent Constructor
Child initialization block
Child Constructor

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

76
CKR666

Il y a plusieurs règles en jeu

  • les blocs statiques sont toujours exécutés avant la création de l'objet. C'est pourquoi vous voyez les messages d'impression des blocs statiques parents et enfants.
  • À présent, 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. Alors maintenant, votre parent est créé et le programme peut continuer à créer une classe enfant qui sera soumise au même processus. 

Explications:

  1. Le bloc statique du parent est exécuté en premier parce qu'il est chargé en premier et que des blocs statiques sont appelés lors du chargement de la classe. 
48
Petr Mensik

J'apprends visuellement alors voici une représentation visuelle de l'ordre sous la forme d'un SSCCE :

public class Example {

  static {
    step(1);
  }

  public static int step_1 = step(2);
  public int step_6 = step(6);

  public Example() {
    step(8);
  }

  {
    step(7);
  }

  // Just for demonstration purposes:
  public static int step(int step) {
    System.out.println("Step " + step);
    return step;
  }
}

public class ExampleSubclass extends Example {

  {
    step(9);
  }

  public static int step_3 = step(3);
  public int step_10 = step(10);

  static {
    step(4);
  }

  public ExampleSubclass() {
    step(11);
  }

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

Cela imprime:

Step 1
Step 2
Step 3
Step 4
Step 5
Step 6
Step 7
Step 8
Step 9
Step 10
Step 11
Step 12

Gardez à l'esprit que l'ordre des static parts est important; Examinez la différence entre l'ordre de Example's static et ExampleSubclass.

Notez également que le bloc d'initialisation d'instance est toujours exécuté avant le constructeur, quel que soit l'ordre. Cependant, l'ordre entre un bloc d'initialisation et un initialiseur de champ est important.

38
Ben Leggiero

Première classe enfant exécutée seulement (commentez la clause extend) pour voir le flux simple.

seconde - aller à Bloc statique vs bloc initialiseur en Java? & lire la réponse acceptée par là.

Modifier:

  1. L'exécution se déroule de la manière SIC - Initializer & Constructor statique (non statique).
  2. Les initialiseurs (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 super-classe directe doit être initialisée - http://docs.Oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4 (d'où parent static le bloc apparaît en premier).
10
Raúl

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é lors du chargement de la classe. Ceci est initialiser avec les variables statiques. Il est principalement utilisé dans JDBC. Le bloc statique en Java est exécuté chaque fois qu'une classe est chargée. Ceci est également appelé bloc d'initialisation statique. Le bloc statique en Java s’initialise lorsque la classe est chargée en mémoire, c’est-à-dire lorsque la machine virtuelle Java lit le code octet. L'initialisation peut être n'importe quoi; il peut s'agir d'une initialisation de variable ou de tout autre élément devant être partagé par tous les objets de cette classe. Un bloc statique est un bloc de code normal entouré d'accolades {} et est précédé d'un mot clé static.

donc bloc statique exécuté en premier.

Blocs d'initialisation d'instance: s'exécute chaque fois que l'instance de la classe est créée.

so next Bloc d'initialisation exécuté lors de la création d'une instance de la classe.

puis constructeur exécuté

5
rohan kamat
  • Les blocs init 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 init stat commence à partir de 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 quel que soit l'endroit où le bloc statique est présent dans la classe.

(Dans votre code, les blocs statiques parents seront d'abord exécutés, puis les blocs statiques de la classe enfant.)

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

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

  • Le constructeur par défaut de la classe Child est exécuté. 
  • Il appellera le super (); constructeur. 
  • Ensuite, le constructeur de la super classe est exécuté. 
  • La classe Parent exécutera son super (); appel. 
  • Après cela, les blocs init de l’instance dans la classe Parent sont exécutés (de haut en bas). 
  • Ensuite, le code dans le constructeur est exécuté (le cas échéant). 
  • Ensuite, il retournera à la classe Child et exécutera les blocs init de l'instance de la classe Child. 
  • Enfin, le code du constructeur enfant est exécuté (si existant).
4

Voici ce que j'ai trouvé en me préparant pour une certification.

Pendant que nous exécutons une classe, la première initialisation de blocs statiques/de variables statiques se produit. S'il y a plusieurs blocs statiques, il l'exécutera dans l'ordre dans lequel il apparaît.

Ensuite, il exécutera les blocs init/initialisation de la variable d’instance. Si plusieurs blocs init/initialisations sont présents, il l’exécutera dans l’ordre dans lequel il apparaît

Ensuite, il se penchera sur le constructeur.

3
PRAVEEN PS

Il serait très utile de vérifier le processus de construction d’objet avec un débogueur pas à pas, avec une vue dans laquelle vous pouvez voir comment votre objet se déplace à travers les phases. J'ai trouvé cela très utile pour éclaircir la perspective d'un point de vue supérieur. Eclipse peut vous aider avec ceci avec son étape de débogueur dans la fonction.

3
Mihai Savin

Je voulais juste partager mes découvertes ... J'ai lu dans l'une des réponses sur un autre thread que les blocs statiques étaient d'abord exécutés avant les champs statiques, ce qui n'est pas correct. Cela dépend de ce qui vient en premier, champ statique ou bloc statique. Regardez ci-dessous le code. Il va essayer de mettre les choses en perspective.

  1. La machine virtuelle Java recherche une classe qui a un objet public void static (String args []) afin de pouvoir charger cette classe.
  2. Il initialise ensuite les champs statiques de cette classe (s'ils viennent avant les blocs statiques). Ces champs peuvent appeler des méthodes statiques de cette classe ou d'une autre. S'ils appellent une méthode statique de cette classe, cette méthode est servie. S'ils appellent la méthode statique d'une autre classe, les champs ou les blocs statiques de cette classe (en fonction de ce qui vient en premier) sont d'abord initialisés, puis cet appel de méthode est servi.
  3. Ensuite, il se déplace vers des blocs statiques.
  4. Cela revient à la méthode principale.

    class TestLab {
    static int method(String a) {
        System.out.println("in static method of TestLab" + " Coming from " + a);
        System.out.println("b is " + b);
        return 6;
    }
    
    static int a = method("Line 11");
    static int b = 7;
    
    TestLab() {
        System.out.println("Inside test lab constructor");
    }
    
    static {
        System.out.println("In static block of TestLab");
    }
    
    }
    
    public class Test1 {
    public static void main(String[] args) {
        System.out.println("inside main method of Test 1");
        int a = TestLab.method("Line 26");
    }
    
    // static Test ref=new Test();
    Test1() {
        System.out.println("Default Constructor of Test1");
    }
    
    {
        System.out.println("In instance block of Test1");
    }
    static int d = TestLab.method("Line 37");
    static int e = methodOfTest1();
    static {
        System.out.println("In Static Block of Test1");
    }
    
    static int methodOfTest1() {
        System.out.println("inside static method:mehtodOfTest1()");
        return 3;
    }
    }
    

Voici la sortie:

in static method of TestLab Coming from Line 11
b is 0
In static block of TestLab
in static method of TestLab Coming from Line 37
b is 7
inside static method:mehtodOfTest1()
In Static Block of Test1
inside main method of Test 1
in static method of TestLab Coming from Line 26
b is 7
3
pragun

flux de contrôle est-

bloc statique -> Bloc d’initialisation -> et enfin Constructeur.

bloc statique -> Ce bloc statique sera exécuté une seule fois lorsque le contrôle arrivera dans la classe. (JVM Load this class)

Bloc d'initialisation -> Ce bloc d'initialisation est exécuté chaque fois qu'un nouvel objet est créé pour la classe(il sera exécuté à partir de la deuxième instruction du constructeur, puis des instructions suivantes du constructeur. /ce())

Constructeur -> Ce sera à chaque fois qu'un nouvel objet est créé.

1
Prakash VL

1.Le bloc d'initialisation statique s'exécute au moment du chargement de la classe uniquement ..... 2. Le bloc 2.Init s'exécute chaque fois avant de créer l'objet de la classe.

lien: - https://www.youtube.com/watch?v=6qG3JE0FbgA&t=2s

0
Java Tutorial

Le bloc statique est exécuté lorsqu'une classe est chargée dans la machine virtuelle Java. Alors que le bloc init est copié dans le constructeur dont l'objet sera créé et exécuté avant la création de l'objet.

0
Sunil Kumar Jha