2011-12-15 17 views
70

Non riesco a capire il seguente testo ... Significa che <clinit> è per costruttori vuoti? Perché è importante avere due versioni differenti?Java: Qual è la differenza tra <init> e <clinit>?

https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html

2.9. Special Methods 

A livello della macchina virtuale Java, ogni costruttore (§2.12) appare come un metodo di inizializzazione istanza che ha il nome speciale <init>. Questo nome è fornito da un compilatore. Poiché il nome <init> non è un identificatore valido, non può essere utilizzato direttamente in un programma scritto nel linguaggio di programmazione Java. I metodi di inizializzazione dell'istanza possono essere richiamati solo all'interno della macchina virtuale Java mediante l'istruzione invokespecial e possono essere invocati solo in istanze di classe non inizializzate. Un metodo di inizializzazione dell'istanza accetta le autorizzazioni di accesso (§2.7.4) del costruttore da cui è stato derivato .

Una classe o un'interfaccia ha al massimo un metodo di inizializzazione di classe o di interfaccia ed è inizializzato (§2.17.4) richiamando il metodo . Il metodo di inizializzazione di una classe o di un'interfaccia è statico e non accetta argomenti. Ha il nome speciale <clinit>. Questo nome è fornito da un compilatore. Poiché il nome <clinit> non è un identificatore valido , non può essere utilizzato direttamente in un programma scritto nel linguaggio di programmazione Java . I metodi di inizializzazione di classe e interfaccia vengono richiamati implicitamente dalla macchina virtuale Java; non sono mai richiamati direttamente da qualsiasi Java virtual machine inw2struction, ma sono invocati solo indirettamente come parte del processo di inizializzazione della classe.

risposta

107

<init> è il (o uno dei) costruttore (i) per l'istanza e l'inizializzazione del campo non statico.

<clinit> sono i blocchi di inizializzazione statici per la classe e l'inizializzazione del campo statico.

class X { 

    static Log log = LogFactory.getLog(); // <clinit> 

    private int x = 1; // <init> 

    X(){ 
     // <init> 
    } 

    static { 
     // <clinit> 
    } 

} 
+2

Cosa significa 'CL' stand for? –

+9

La mia ipotesi è "classe". – Thilo

+2

@Thilo è interessante perché la JVM tratta una definizione di classe come solo un altro tipo di oggetto. –

12

La differenza tra <init> e <clinit> è che <init> viene utilizzato per metodi costruttori che inizializzare un oggetto esempio, considerando <clinit> viene utilizzato per inizializzare l'oggetto della classe stessa. Ad esempio, l'inizializzazione di qualsiasi campo static di livello classe viene eseguita in <clinit> quando la classe viene caricata e initalizzata.

0

Solo per aggiungere Se si utilizza il metodo Class.forName, solo inizializza la classe. Quindi, all'interno di questo metodo, effettua una chiamata solo per clinit e quando si usa newInstance sull'oggetto restituito da forName, chiamerà init per l'inizializzazione dell'istanza. Puoi usare sotto il codice per vederlo nel debug.

public class ByteCodeParent 
{ 
public static String name="ByteCode"; 
public ByteCodeParent() 
{ 
    System.out.println("In Constructor"); 
} 

static 
{ 
    System.out.println("In Static"); 
} 

{ 
    System.out.println("In Instance"); 
} 

Per testare, utilizzare

Class<ByteCodeParent> bcp2 =(Class<ByteCodeParent>) Class.forName("ByteCodeParent"); 
ByteCodeParent bcp4= bcp2.newInstance(); 
Problemi correlati