2011-12-15 27 views
70

No puedo entender el siguiente texto ... ¿Significa que <clinit> es para constructores vacíos? ¿Por qué es importante tener dos versiones diferentes?Java: ¿Cuál es la diferencia entre <init> y <clinit>?

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

2.9. Special Methods 

A nivel de la máquina virtual de Java, cada constructor (§2.12) aparece como un método de inicialización de instancia que tiene el nombre especial <init>. Este nombre es proporcionado por un compilador. Como el nombre <init> no es un identificador válido, no se puede usar directamente en un programa escrito en el lenguaje de programación Java. Los métodos de inicialización de instancias solo pueden invocarse dentro de la máquina Java virtual mediante la instrucción invokespecial, y solo pueden invocarse en instancias de clase no inicializadas. Un método de inicialización de instancia asume los permisos de acceso (§2.7.4) del constructor del cual se derivó .

Una clase o interfaz tiene como máximo un método de inicialización de clase o interfaz y se inicializa (§2.17.4) invocando el método . El método de inicialización de una clase o interfaz es estático y no toma argumentos. Tiene el nombre especial <clinit>. Este nombre es suministrado por un compilador. Como el nombre <clinit> no es un identificador válido, no se puede usar directamente en un programa escrito en el lenguaje de programación Java . Los métodos de inicialización de clase e interfaz son invocados implícitamente por la máquina virtual Java; nunca son invocados directamente desde cualquier máquina virtual Java inw2struction, pero son invocados solo de forma indirecta como parte del proceso de inicialización de clases.

Respuesta

107

<init> es el (o los) constructor (es) para la instancia y la inicialización de campo no estática.

<clinit> son los bloques de inicialización estáticos para la clase y la inicialización del campo estático.

class X { 

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

    private int x = 1; // <init> 

    X(){ 
     // <init> 
    } 

    static { 
     // <clinit> 
    } 

} 
+2

¿Qué significa 'CL' representan? –

+9

Mi suposición es "clase". – Thilo

+2

@Thilo que es interesante porque la JVM trata una definición de clase como otro tipo de objeto también. –

12

La diferencia entre <init> y <clinit> es que <init> se usa para los métodos constructor que inicializar una instancia de objeto, mientras que <clinit> se utiliza para inicializar el propio objeto de clase. Por ejemplo, la inicialización de cualquier campo de nivel de clase static se realiza en <clinit> cuando la clase se carga e inicia.

0

Solo para agregar Si usa el método Class.forName, solo inicia la clase. Entonces, desde este método, realiza una llamada solo a clinit y cuando usa newInstance en el objeto devuelto por forName, llamará a init para la inicialización de la instancia. Puede usar el código a continuación para verlo en depuración.

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"); 
} 

Para probar, usar

Class<ByteCodeParent> bcp2 =(Class<ByteCodeParent>) Class.forName("ByteCodeParent"); 
ByteCodeParent bcp4= bcp2.newInstance(); 
Cuestiones relacionadas