2009-07-15 3 views
9

Ok donc c'est une question de débutant sur Java, mais je n'arrive pas à comprendre.Explication de la manière dont le classloader charge les variables statiques

J'ai le code suivant dans ma classe

private static final String [] LIST_CODE = gerarListCode(); 
private static final int [][] LIST_INTEGER = new int [][] { 
     {947,947}, {110,103}, 
     {947,958}, {110,120}, 
     {947,954}, {103,107}, 
     {947,967}, {110,99,104}}; 

private static String [] gerarListCode() 
    { 
     String [] listCode = new String [LIST_INTEGER.length]; 

     for (int i=0 ; i<LIST_INTEGER.length ; i++) 
     { 
      //do some stuff  
     } 

     return listaUnicode; 
    } 

Ce code me donne une exception d'initialisation en raison d'une NullPointerException dans la ligne suivante

String [] listCode = new String [LIST_INTEGER.length]; 

Semble la LIST_INTEGER variable est nulle à ce temps.

Quelqu'un peut-il expliquer pourquoi? le processus du chargeur de classes est-il linéaire, en d'autres termes, invoque-t-il la méthode avant de charger toutes les autres variables?

+1

déplacer la déclaration de LIST_INTEGER à la ligne avant LIST_CODE – Ron

Répondre

11

Oui, en somme, c'est linéaire.

« Ce que le compilateur ne fait est de produire en interne une seule routine d'initialisation classe qui combine tous les initialiseurs variables statiques et tous les initialiseur statique blocs de code, dans l'ordre qu'ils apparaissent dans la déclaration de classe Cette procédure d'initialisation unique est exécutée automatiquement , une seule fois, lorsque la classe est chargée en premier. "

Tiré de Java en un mot.

http://www.developer.com/java/other/article.php/2238491

Vous devez définir les variables et les initialiser dans un bloc de intitializer statique dans l'ordre, ou vous pouvez échanger l'ordre des déclarations comme suit:

private static final int [][] LIST_INTEGER = new int [][] { {947,947}, {110,103}, 
     {947,958}, {110,120}, 
     {947,954}, {103,107}, 
     {947,967}, {110,99,104}}; 

private static final String [] LIST_CODE = gerarListCode(); 
+0

Strictement parlant, ce n'est pas quand la classe est chargée mais plus tard, quand elle est initialisée. –

4

La JVM va, en effet, initialiser les champs statiques dans l'ordre dans lequel ils les rencontrent.

Les champs statiques d'une classe sont initialisés lorsque la classe est rencontrée pour la première fois par la JVM. Selon Java Puzzlers, puzzle 49 (qui passe à la référence JLS 4.12.5), les champs statiques sont d'abord mis à leurs valeurs par défaut. Les variables d'objet sont définies sur null, int s sont définies sur 0, etc. Après cela, leurs initialiseurs sont exécutés dans l'ordre d'apparition. Par conséquent, dans votre exemple, LIST_CODE et LIST_INTEGER sont d'abord définis sur null. Ensuite, LIST_CODE est initialisé en appelant gerarListCode(). LIST_INTEGER est toujours null lorsque cette méthode est exécutée. Seulement après cela, LIST_INTEGER est initialisé avec la valeur littérale que vous donnez dans votre exemple.

+0

Cela n'a rien à voir avec le chargeur de classe. Il est implémenté par javac en créant l'initialiseur statique dans l'ordre de la source. –

+0

Merci pour le crochet, Tom! J'ai mis à jour ma réponse. – jqno

Questions connexes