Votre Test
compile:
public class Test {
public static final Test me;
public static final Integer I;
public static final String S = "abc";
static {
me = new Test();
I = Integer.valueOf(4);
}
public Test() {
System.out.println(I);
System.out.println("abc");
}
public static Test getInstance() { return me; }
public static void main(String[] args) {
Test.getInstance();
}
}
Comme vous pouvez le voir, le constructeur Test
est appelée avant I
est initialisé. C'est pourquoi il imprime "null"
pour I
. Si vous étiez à inverser l'ordre de déclaration, pour me
et I
, vous obtiendrez le résultat escompté, car I
serait initialisé avant que le constructeur est appelé. Vous pouvez également modifier le type I
de Integer
de int
.
Parce qu' 4
des besoins pour obtenir autoboxed (c'est à dire, enveloppé dans un Integer
objet), il n'est pas une constante de compilation et fait partie de l'initialiseur statique bloc. Toutefois, si le type ont été int
, le nombre 4
serait une constante de compilation, de sorte qu'il ne serait pas besoin d'être explicitement initialisée. Parce qu' "abc"
est une constante de compilation, la valeur de S
est imprimé comme prévu.
Si vous devez le remplacer,
public static final String S = "abc";
avec,
public static final String S = new String("abc");
Ensuite, vous verrez la sortie de l' S
est "null"
. Pourquoi est-ce arrivé? Pour la même raison pourquoi I
également des sorties "null"
. Des domaines comme ceux qui ont littérale, des valeurs constantes (qui n'a pas besoin de l'autoboxing, comme String
) sont attribués à l' "ConstantValue"
de l'attribut lors de la compilation, ce qui signifie que leur valeur peut être résolu simplement en regardant dans la classe' constante de la piscine, sans avoir besoin d'exécuter n'importe quel code.