99 votes

Dans quel ordre statique et un initialiseur de blocs en Java?

Dire un projet contient plusieurs classes, dont chacune a un initialiseur statique bloc. Dans quel ordre ces blocs exécuter? Je sais que dans une classe, ces blocs sont exécutés dans l'ordre où ils apparaissent dans le code. J'ai lu que c'est la même chose dans des classes, mais des exemples de code que j'ai écrit n'est pas d'accord avec ça. J'ai utilisé ce code:

package pkg;

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

class Parent extends Grandparent {
    // Instance init block
    {
        System.out.println("instance - parent");
    }

    // Constructor
    public Parent() {
        System.out.println("constructor - parent");
    }

    // Static init block
    static {
        System.out.println("static - parent");
    }
}

class Grandparent {
    // Static init block
    static {
        System.out.println("static - grandparent");
    }

    // Instance init block
    {
        System.out.println("instance - grandparent");
    }

    // Constructor
    public Grandparent() {
        System.out.println("constructor - grandparent");
    }
}

class Child extends Parent {
    // Constructor
    public Child() {
        System.out.println("constructor - child");
    }

    // Static init block
    static {
        System.out.println("static - child");
    }

    // Instance init block
    {
        System.out.println("instance - child");
    }
}

et a obtenu ce résultat:

DÉMARRER
statique - grands-parents
statique - parent
statique - enfant
exemple - grands-parents
constructeur - grands-parents
exemple - parent
constructeur - parent
exemple - enfant
constructeur - enfant
FIN

La réponse évidente est que les blocs de courir avant de leurs enfants, mais qui pourrait n'être qu'une coïncidence et n'aide pas si les deux classes ne sont pas dans la même hiérarchie.

EDIT:

J'ai modifié mon code en exemple par l'ajout de ce à LoadTest.java:

class IAmAClassThatIsNeverUsed {
    // Constructor
    public IAmAClassThatIsNeverUsed() {
        System.out.println("constructor - IAACTINU");
    }

    // Instance init block
    {
        System.out.println("instance - IAACTINU");
    }

    // Static init block
    static {
        System.out.println("static - IAACTINU");
    }
}

Comme le laisse entendre le nom de la classe, je n'ai jamais fait référence à la nouvelle classe n'importe où. Le nouveau programme produit le même résultat que l'ancien.

94voto

Keith Randall Points 17518

Voir la section 12.4 et 12.5 de la Java Language Specification, ils vont dans le détail sanglant à ce sujet (12.4 statique et 12,5 pour les variables d'instance).

Pour l'initialisation statique (article 12.4):

Une classe ou une interface de type T sera initialisé immédiatement avant la première occurrence de l'un des cas suivants:

  • T est une classe et une instance de T est créé.
  • T est une classe et une méthode statique déclaré par T est invoquée.
  • Un champ statique déclaré par T est attribué.
  • Un champ statique déclaré par T est utilisé et que le champ n'est pas une constante variable (§4.12.4).
  • T est une classe de haut niveau (§7.6), et une instruction assert (§14.10) lexicalement imbriquée dans T (§8.1.3) est exécutée.

(et plusieurs belette-parole de clauses)

63voto

Chris Jester-Young Points 102876

L'initialiseur statique d'une classe est exécuté lorsque la classe est d'abord accessible, que ce soit pour créer une instance, ou l'accès à une méthode statique ou sur le terrain.

Ainsi, pour plusieurs classes, cela dépend totalement le code qui est exécuté à cause de ces classes chargées.

35voto

Pops Points 10137

Keith et de Chris réponses sont à la fois super, je suis juste en ajoutant un peu plus en détail de ma question.

Statique init blocs exécuter dans l'ordre dans lequel les classes sont initialisés. Alors, de quel ordre est-ce? Par JLS 12.4.1:

Une classe ou une interface de type T sera initialisé immédiatement avant la première occurrence de l'un des cas suivants:

  • T est une classe et une instance de T est créé.
  • T est une classe et une méthode statique déclaré par T est invoquée.
  • Un champ statique déclaré par T est attribué.
  • Un champ statique déclaré par T est utilisé et que le champ n'est pas une constante variable (§4.12.4).
  • T est un haut-niveau de la classe, et une instruction assert (§14.10) lexicalement imbriquée dans T est exécutée.

L'Invocation de certains réfléchissant méthodes dans la classe de la Classe et dans le paquet java.lang.reflètent également les causes de la classe ou de l'interface d'initialisation. Une classe ou une interface ne sera pas initialisé en vertu de toute autre circonstance.

Pour illustrer, voici un pas à pas de ce qui se passe dans l'exemple:

  1. Entrée principale
  2. Print "DÉMARRER"
  3. Tentative de créer de la première instance de l'Enfant, qui exige de l'initialisation de l'Enfant
  4. La tentative d'initialisation de l'Enfant provoque l'initialisation de Parent
  5. La tentative d'initialisation Parent provoque l'initialisation de grands-parents
  6. Au début de l'initialisation d'un grand-parent, grand-parent de l'initialisation statique bloc est exécuté
  7. Techniquement, l'Objet devient le dernier mot dans la chaîne d'initialisation par le fait d'être grand-parent du parent, mais il n'a rien à contribuer
  8. Après les grands-parents de l'initialisation statique bloc se termine, le programme revient au Parent du bloc d'initialisation statique
  9. Après la Mère de l'initialisation statique bloc se termine, le programme revient à l'Enfant initialisation statique bloc
  10. À ce stade, l'Enfant est initialisé, de sorte que son constructeur peut procéder
  11. Depuis IAmAClassThatIsNeverUsed ne fait jamais référence, aucun de ses code jamais pistes, y compris l'initialiseur statique blocs
  12. Le reste de cette procédure ne concerne pas les initialiseurs statiques et est fourni uniquement à des fins d'exhaustivité
  13. Enfant du constructeur appelle implicitement à super() (c'est à dire, Parent du constructeur)
  14. Parent du constructeur appelle implicitement à super() (c'est à dire, les grands-parents du constructeur)
  15. Grands-parents constructeur fait la même chose, qui n'a pas d'effet (encore une fois, l'Objet n'a rien à contribuer)
  16. Immédiatement après les grands-parents du constructeur de l'appel à super() est livré grands-parents en instance d'initialiseur de bloc
  17. Le reste des grands-parents du constructeur constructeur s'exécute et le constructeur se termine
  18. Le programme revient à la Mère du constructeur, immédiatement après son appel à super() (c'est à dire, les grands-parents du constructeur) résout
  19. Comme ci-dessus, Parent de l'instance de l'initialiseur fait sa chose et son constructeur se termine
  20. De même, le programme retourne et se termine Enfant du constructeur
  21. À ce stade, l'objet a été instancié
  22. Print "FIN"
  23. Mettre fin normalement

1voto

Bala Points 1088

L'initialisation d'une classe consiste en l'exécution de ses initialiseurs statiques et les initialiseurs statiques champs (variables de classe) a déclaré dans la classe.

L'initialisation de l'interface consiste en l'exécution du initialiseurs pour les champs (constantes) déclarées dans l'interface.

Devant une classe est initialisée, sa super-classe directe doit être initialisée, mais les interfaces implémentées par la classe ne sont pas initialisés. De même, la superinterfaces d'une interface ne sont pas initialisées avant que l'interface est initialisé.

0voto

Martin Tapp Points 360

Vous pouvez avoir plusieurs statique et de l'instance d'initialiseurs dans la même classe, donc

  • Les initialiseurs statiques sont appelés dans l'ordre textuel ils sont déclaré (à partir de 12.4.2)
  • Exemple initialiseurs sont appelés dans l'ordre textuel ils sont déclaré (à partir de 12.5)

Chacun est exécutée comme si elle était un seul bloc.

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