2013-04-10 7 views
10

Ich weiß, dass die neue, dup, invokespecial und astore Bytecode Muster die Instanz initializer Methode aufrufen wird <init>, wenn jemand beispielsweise eine Java-Klasse aus der Sicht der Java-Sprache, aber ich, die nie herausfinden Rufen Sie die spezielle Methode <clinit> auf und wann passiert das?Wer ruft die Klasseninitialisierungsmethode <clinit> auf und wann?

Meine Schätzung ist, dass <clinit> aufgerufen wird vor<init> Methode. Kann irgendein Körper mir einige Informationen geben, um es zu beweisen? Ist dies in der JVM-Spezifikation oder der Java-Sprachspezifikation dokumentiert?

Antwort

7

JVM spec §2.9. Special Methods:

A-Klasse oder Schnittstelle hat höchstens eine Klasse oder Schnittstelle Initialisierungsverfahren und initialisiert (§5.5) durch dieses Verfahren aufgerufen wird. Die Initialisierungsmethode einer Klasse oder Schnittstelle hat den speziellen Namen <clinit>, nimmt keine Argumente an und ist ungültig (§4.3.3). Der Name <clinit> wird von einem Compiler geliefert. Da der Name kein gültiger Bezeichner ist, kann er nicht direkt in einem Programm verwendet werden, das in der Programmiersprache Java geschrieben wurde. Klassen- und Schnittstelleninitialisierungsmethoden werden von der Java Virtual Machine implizit aufgerufen; Sie werden niemals direkt von einer Java Virtual Machine-Anweisung aufgerufen, sondern nur indirekt als Teil des Klasseninitialisierungsprozesses aufgerufen.

Weitere Details zum Klasseninitialisierungsprozess finden Sie unter Chapter 5.

1

<clinit> sind die statischen Initialisierungsblöcke für die Klassen- und statische Feldinitialisierung und werden von JVM aufgerufen.

Java Spec sagt http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#12174

The initialization method of a class or interface is static and takes no arguments. It has the special name <clinit>. This name is supplied by a compiler. Because the name <clinit> is not a valid identifier, it cannot be used directly in a program written in the Java programming language. Class and interface initialization methods are invoked implicitly by the Java virtual machine 
6

<clinit> ist eine statische Methode von javac hinzugefügt und durch JVM nach Klasse Laden genannt. Wir können diese Methode im Klassen-Bytecode mit Bytecode-Umrißwerkzeugen sehen. Beachten Sie, dass <clinit> hinzugefügt wird nur dann, wenn eine Klasse statische initilization benötigt, z

public class Test1 { 
    static int x = 1; 

    public static void main(String[] args) throws Exception { 
    } 
} 

public class Test2 { 
    static final int x = 1; 

    public static void main(String[] args) throws Exception { 
    } 
} 

Test1 hat <clinit> weil sein Feld x mit 1 initialisiert werden muss; während Test2 keine <clinit> Methode hat, weil seine x eine Konstante ist.

Es ist auch interessant zu beachten, dass Class.forName hat boolen intialize Parameter, der bestimmt, ob die Klasse nach dem Laden initialisiert werden soll oder nicht.

+1

"Beachten Sie, dass nur hinzugefügt wird, wenn eine Klasse statische Initialisierung benötigt" - jede Quelle dafür? – siledh

+0

es ist aus der Praxis (Tests) um ehrlich zu sein, auch der gesunde Menschenverstand schlägt das gleiche, sicher Theres einen Absatz in JLS darüber –

Verwandte Themen