2010-08-17 7 views
97

Quand les champs statiques sont-ils initialisés? Si je n'instancie jamais une classe, mais que j'accède à un champ statique, est-ce que TOUS les blocs statiques et les méthodes statiques privées sont utilisés pour instancier des champs statiques privés appelés (dans l'ordre) à cet instant?Quand l'initialisation de classe statique se produit-elle?

Que faire si j'appelle une méthode statique? Est-ce qu'il exécute également tous les blocs statiques? Avant la méthode?

+0

similaires pour les blocs statiques initialiseur: http://stackoverflow.com/questions/ 2007666/in-what-order-do-static-initializer-blocks-in-java-run –

Répondre

138

initialisation statique d'une classe se produit normalement immédiatement avant la première fois que l'un des événements suivants se produisent:

  • une instance de la classe est créée,
  • une méthode statique de la classe est invoquée,
  • un champ statique de la classe est attribué,
  • un champ statique non constante est utilisée, ou
  • pour une classe de niveau supérieur, une instruction d'assertion lexicalement imbriquée dans la classe est réalisé.

Voir JLS 12.4.1.

Il est également possible de forcer une classe à initialiser (si elle n'a pas déjà initialisé) en utilisant Class.forName(fqn, true, classLoader) ou la forme courte Class.forName(fqn)

+0

Merci pour l'info supplémentaire. –

+5

+1 pour donner la référence JLS – Moshe

+4

Notez également que la forme plus courte 'Class.forName (className)' force également l'initialisation car elle équivaut à 'Class.forName (className, true, currentLoader)'. – user113215

1

Oui, tous les initialiseurs statiques sont exécutés avant d'accéder à la classe pour la première fois. Si c'était autrement, je dirais que c'est un bug.

+0

Il existe des moyens de faire référence à une classe sans l'initialiser. –

11

Les zones statiques sont initialisées pendant la "phase" initialization du chargement de classe (chargement, liaison et initialisation) qui inclut les initialiseurs statiques et les initialisations de ses champs statiques. Les initialiseurs statiques sont exécutés dans un ordre textuel tel que défini dans la classe.

Prenons l'exemple:

public class Test { 

    static String sayHello() { 
     return a; 
    } 

    static String b = sayHello(); // a static method is called to assign value to b. 
           // but its a has not been initialized yet. 

    static String a = "hello"; 

    static String c = sayHello(); // assignes "hello" to variable c 

    public static void main(String[] arg) throws Throwable { 
     System.out.println(Test.b); // prints null 
     System.out.println(Test.sayHello()); // prints "hello" 
    } 
} 

Le Test.b imprime null parce que quand la sayHello a été appelé portée statique, n'a pas été initialisé la a variable statique.

+6

Strictement parlant, l'initialisation n'est pas une "phase" de chargement de classe. En effet, certaines classes * peuvent être chargées mais jamais initialisées si l'application ne les utilise pas réellement. –

+0

@Stephen C Vous avez raison, je l'ai utilisé pour un manque d'un meilleur terme, peut-être que je vais le citer. – naikus

+0

@StephenC cela signifie-t-il que pendant le chargement de la classe, il affecte de la mémoire aux variables statiques (& méthodes) mais ces variables statiques ne sont pas initialisées avec les valeurs fournies dans le code? parce qu'ici il semble que lorsque b-> sayHello() -> a, 'a' est en mémoire mais que la valeur n'y est pas encore assignée. –

Questions connexes