Static-block in Java nicht ausgeführt
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);
}
}
Ich weiß, dass eine static
block wird ausgeführt wenn die Klasse geladen wird. Aber in diesem Fall die Instanz-variable innerhalb der Klasse Mno
ist final
, weil der, dass die static
- block wird nicht ausgeführt.
Warum ist das so? Und wenn ich die entfernen würde, die final
, würde es funktionieren?
Denen Speicher zugewiesen, der erste, der static final
variable oder die static
block?
Wenn aufgrund der final
access-modifier der Klasse nicht geladen, wie kann dann die variable get-Speicher?
- Was ist die genaue Fehlermeldung und die Nachricht, die Sie bekommen?
- es ist kein Fehler, seine Zweifel
Du musst angemeldet sein, um einen Kommentar abzugeben.
static final int
Feld ist ein compile-Zeit-Konstante und sein Wert ist fest in der Ziel-Klasse ohne Verweis auf deren Herkunft.In spezifischen Details, die den kompilierten bytecode entspricht:
Sobald Sie entfernen
final
ist es nicht mehr eine compile-Zeit-Konstante und die spezielle oben beschriebene Verhalten gilt nicht. DieMno
Klasse geladen wird, wie erwartet, und seine statische Initialisierer ausgeführt.Der Grund, warum die Klasse nicht geladen ist, ist, dass
VAL
istfinal
UND es wird initialisiert mit ein konstanter Ausdruck sein (9090). Wenn, und nur wenn diese beiden Bedingungen erfüllt sind, wird die Konstante zur Kompilierzeit ausgewertet, und "hardcoded", wo nötig.Um zu verhindern, dass der Ausdruck ausgewertet wird zur compile-time (und die JVM laden Sie Ihre Klasse), können Sie entweder:
entfernen Sie das Schlüsselwort final:
ändern oder der rechten Seite Ausdruck zu etwas, was nicht konstant (auch wenn die variable noch final):
Wenn Sie sehen, generiert der bytecode mit
javap -v Test.class
main() kommt heraus wie:Können Sie deutlich sehen, in "
11: sipush 9090
", dass statische, endgültige Wert wird direkt benutzt, weil Mno.VAL ist eine compile-Zeit-Konstante. Daher ist es nicht erforderlich zu laden Mno-Klasse. Somit static-block von Mno wird nicht ausgeführt.Führen Sie den static-block durch manuelles laden Mno wie folgt:
1)Eigentlich muss man nicht verlängert, die Mno-Klasse, so bei der Kompilierung gestartet wird, generiert Konstante variable VAL und wenn die Ausführung gestartet, wenn diese variable wird benötigt, seine Last, das ist aus dem Gedächtnis.so ist es nicht erforderlich, Ihre Klasse Referenz, so dass statische bock wird nicht ausgeführt.
2)wenn Sie Eine Klasse erweitern, die Mno-Klasse zu dieser Zeit, dass der static-block wird in Eine Klasse eingebunden, wenn Sie dies tun, dann, dass der static-block wird ausgeführt.
zum Beispiel..
public class A extends Mno{
Soweit ich weiß, wird es ausgeführt werden in der Reihenfolge des Auftretens. Zum Beispiel :
drucken
Habe es gerade getestet und die Statik werden initialisiert (=> drucken), wenn die Klasse "Statique" tatsächlich verwendet wird und "hingerichtet" in einem anderen Stück code (in meinem Fall habe ich "neue Statique()".
Statique
Klasse by doingnew Statique()
. Während in der FrageMno
- Klasse wird nicht geladen.