class Test {
public static void main(String arg[]) {
System.out.println("**MAIN METHOD");
System.out.println(Mno.VAL); // SOP(9090);
System.out.println(Mno.VAL + 100); // SOP(9190);
}
}
class Mno {
final static int VAL = 9090;
static {
System.out.println("**STATIC BLOCK OF Mno\t: " + VAL);
}
}
Je sais qu'un static
bloc exécuté lors du chargement de la classe. Mais dans ce cas, la variable d'instance à l'intérieur de la classe Mno
est final
, à cause de cela, le static
bloc ne s'exécute pas.
Pourquoi est-ce si? Et si je supprimais le final
, cela fonctionnerait-il bien?
Quelle mémoire sera allouée en premier, la static final
variable ou le static
bloc?
Si, en raison du final
modificateur d'accès, la classe n'est pas chargée, comment la variable peut-elle obtenir de la mémoire?
java
static
access-modifiers
Sthita
la source
la source
Réponses:
static final int
champ est une constante de compilation et sa valeur est codée en dur dans la classe de destination sans référence à son origine;Plus précisément, le bytecode compilé correspond à ceci:
Dès que vous supprimez
final
, il ne s'agit plus d'une constante de compilation et le comportement spécial décrit ci-dessus ne s'applique pas. LaMno
classe est chargée comme prévu et son initialiseur statique s'exécute.la source
La raison pour laquelle la classe n'est pas chargée est qu'elle
VAL
estfinal
ET qu'elle est initialisée avec une expression constante (9090). Si, et seulement si, ces deux conditions sont remplies, la constante est évaluée au moment de la compilation et "codée en dur" si nécessaire.Pour éviter que l'expression ne soit évaluée au moment de la compilation (et pour que la JVM charge votre classe), vous pouvez soit:
supprimer le mot clé final:
ou changez l'expression de droite en quelque chose de non constant (même si la variable est toujours finale):
la source
Si vous voyez le bytecode généré en utilisant
javap -v Test.class
, main () sort comme:Vous pouvez clairement voir dans "
11: sipush 9090
" que la valeur finale statique est directement utilisée, car Mno.VAL est une constante de temps de compilation. Par conséquent, il n'est pas nécessaire de charger la classe Mno. Par conséquent, le bloc statique de Mno n'est pas exécuté.Vous pouvez exécuter le bloc statique en chargeant manuellement Mno comme ci-dessous:
la source
En fait, vous n'avez pas étendu cette classe Mno, donc lorsque la compilation démarre, elle génère la constante de la variable VAL et lorsque l'exécution démarre lorsque cette variable est nécessaire, sa charge est de la mémoire. Il n'est donc pas nécessaire que votre classe référence pour que le bock statique ne soit pas exécuté.
si la classe
A
étend la classeMno
, le bloc statique est inclus dans la classeA
si vous faites cela, alors ce bloc statique est exécuté. Par exemple..la source
Autant que je sache, il sera exécuté par ordre d'apparition. Par exemple :
va imprimer
Je viens de le tester et les statiques sont initialisées (=> print) lorsque la classe "Statique" est effectivement utilisée et "exécutée" dans un autre morceau de code (mon cas j'ai fait "new Statique ()".
la source
Statique
classe en faisantnew Statique()
. Alors que dans la question posée, laMno
classe n'est pas du tout chargée.