2009-11-19 7 views
6

Imaginez une classe Java qui possède la plupart des fonctionnalités que vous pouvez trouver dans une classe. Par exemple: il hérite d'une autre classe, implémente quelques interfaces, inclut des constantes 'static final', des constantes finales, des variables statiques, des variables d'instance, un bloc statique, un bloc de code sans nom (code dans {}), constructeurs, méthodes, etc.Dans quel ordre les différentes parties d'une classe sont-elles initialisées lorsqu'une classe est chargée dans la machine virtuelle Java?

Lorsque la classe en question est chargée pour la première fois dans la JVM, dans quel ordre les différentes parties de la classe sont-elles initialisées ou chargées dans la JVM? A quoi ressemble la pile d'appels dans la JVM pour le chargement? Supposons qu'un seul classloader est au travail ici.

Cela remonte aux bases absolues/internes de Java, mais je n'ai pas pu trouver un bon article expliquant la bonne séquence.

Répondre

1

Que diriez-vous de la JLS, en particulier la section 12.4?

+0

réel lisse ... :) Je voudrais avoir le bon terme de recherche Google pour se rendre à la JLS! m'a également frappé que j'aurais pu être en mesure d'exécuter cela à travers le débogueur éclipse ... :( – Thimmayya

3

Cela pourrait être décrit dans la section 2.17.4 of the JVMS 5.0/6

2.17.4 Initialisation

initialisation d'une classe consiste à:

  • l'exécution de ses initialiseurs statiques (§2.11) et
  • les initialiseurs pour les champs statiques (§2.9.2) déclarés dans la classe.

L'initialisation d'une interface consiste à exécuter les initialiseurs pour les champs déclarés dans l'interface (§2.13.3.1). Avant la initialisation d'une classe ou d'une interface, sa super-classe directe doit être initialisée, mais les interfaces implémentées par la classe n'ont pas besoin d'être initialisées. De même, les superinterfaces d'une interface n'ont pas besoin d'être initialisées avant l'initialisation de l'interface.

Une classe ou une interface de type T sera initialisé immédiatement avant l'un des événements suivants se produit:

  • T est une classe et une instance de T est créé.
  • T est une classe et une méthode statique de T est invoquée.
  • Un champ statique non-constant de T est utilisé ou affecté. Un champ constant est un champ qui est (explicitement ou implicitement) à la fois final et statique, et qui est initialisé avec la valeur d'une expression de constante à la compilation. Une référence à un tel champ doit être résolue au moment de la compilation en une copie de la valeur de la constante de compilation, de sorte que les utilisations d'un tel champ n'entraînent jamais l'initialisation.

L'invocation de certaines méthodes dans les classes de bibliothèques (§3.12) provoque également une initialisation de classe ou d'interface. Consultez les spécifications de la bibliothèque de classes de la plate-forme Java 2 (par exemple, classe Class et package java.lang.reflect) pour plus de détails.

L'intention ici est qu'un type a un ensemble d'initialisateurs qui le mettent dans un état cohérent et que cet état soit le premier état qui est observé par d'autres classes. Les initialiseurs statiques et les initialiseurs de variables de classe sont exécutés dans un ordre textuel et peuvent ne pas faire référence aux variables de classe déclarées dans la classe dont les déclarations apparaissent textuellement après l'utilisation, même si ces variables de classe sont dans la portée.Cette restriction est conçue pour détecter, au moment de la compilation, la plupart des initialisations circulaires ou malformées.

Avant l'initialisation d'une classe ou d'une interface, sa super-classe est initialisée si elle n'a pas été initialisée auparavant.


La version mise à jour du Initialization in JVMS 8 is in Chapter 5.5

initialisation d'une classe ou l'interface consiste à exécuter la méthode d'initialisation classe ou interface (§2.9).

Une classe ou de l'interface peut être initialisées, à la suite de:

  • L'exécution d'une des instructions de la machine virtuelle Java new, getstatic, putstatic ou invokestatic qui fait référence à la classe ou de l'interface (§new§getstatic, §putstatic, §invokestatic).
    Toutes ces instructions font référence à une classe directement ou indirectement via une référence de zone ou une référence de méthode.
    Lors de l'exécution d'une nouvelle instruction, la classe ou l'interface référencée est initialisée si elle n'a pas déjà été initialisée.
    Lors de l'exécution d'une instruction getstatic, putstatic ou invokestatic, la classe ou l'interface qui a déclaré le champ ou la méthode résolus est initialisée si elle n'a pas déjà été initialisée.
  • La première invocation d'une instance java.lang.invoke.MethodHandle qui était le résultat de la résolution d'une poignée de méthode par la machine virtuelle Java (§5.4.3.5) et qui a une sorte de 2 (REF_getStatic), 4 (REF_putStatic), 6 (REF_invokeStatic), ou 8 (REF_newInvokeSpecial).
  • Invocation de certaines méthodes de réflexion dans la bibliothèque de classes (§2.12), par exemple, dans la classe Class ou dans le paquet java.lang.reflect.
  • L'initialisation d'une de ses sous-classes.
  • Sa désignation en tant que classe initiale au démarrage de la machine virtuelle Java (§5.2).

Avant l'initialisation, une classe ou interface doivent être liées, qui est, vérifiés, préparés et éventuellement résolus. Étant donné que la machine virtuelle Java est multithread, l'initialisation d'une classe ou d'une interface nécessite une synchronisation soigneuse, car un autre thread peut essayer d'initialiser la même classe ou interface en même temps.
Il est également possible que l'initialisation d'une classe ou d'une interface soit demandée récursivement dans le cadre de l'initialisation de cette classe ou interface.

L'implémentation de la machine virtuelle Java est chargée de prendre en charge la synchronisation et l'initialisation récursive en utilisant la procédure suivante.
Il suppose que l'objet Class a déjà été vérifié et préparé, et que l'objet Class contient l'état qui indique une des quatre situations:

  • Cet objet Class est vérifié et préparé mais non initialisé.
  • Cet objet Class est initialisé par un thread particulier.
  • Cet objet Class est entièrement initialisé et prêt à l'emploi.
  • Cet objet Class est dans un état erroné, peut-être parce que l'initialisation a été tentée et a échoué.
+0

+1 pour votre mise à jour. – sunleo