2009-12-12 13 views
8
class test 
{ 
    test() 
    { 
     System.out.println("Constructor"); 
    } 

    { 
    System.out.println("Hai"); 
    } 

} 
public class sample 
{ 
    public static void main(String [] a) 
    { 
     test t = new test();   
    } 
} 

en el código anterior por qué es que la instrucción dada dentro de los corchetes ((es decir, "Hai") se imprime antes de que se ejecute el constuctor.duda en conceptos básicos de Java?

Respuesta

31

Let expresar con un ejemplo más claro:

public class Test { 

    static { 
     System.out.println("static initializer"); 
    } 

    { 
     System.out.println("instance initializer"); 
    } 

    public Test() { 
     System.out.println("constructor"); 
    } 

} 

y probarlo de la siguiente manera:

public class Main { 

    public static void main(String[] args) { 
     Test test1 = new Test(); 
     Test test2 = new Test(); 
    } 

} 

de salida:

static initializer 
instance initializer 
constructor 
instance initializer 
constructor 

Los inicializadores estáticos se ejecutan sólo vez durante el tiempo de ejecución, específicamente durante la carga de la clase. Los inicializadores de instancia se ejecutan durante cada instanciación antes del constructor.

Puede tener más de uno de ellos y se ejecutarán en el orden en que aparecen en la codificación.

El principal beneficio de los inicializadores de instancias es que se ejecutan independientemente del constructor que use. Se aplican en cada uno de ellos para que no tenga que duplicar la inicialización común sobre todos ellos.

El principal beneficio de los inicializadores estáticos es que se ejecutan solo una vez durante la carga de la clase. Un ejemplo conocido del mundo real es el controlador JDBC. Cuando lo haga

Class.forName("com.example.jdbc.Driver"); 

que sólo ejecuta las static inicializadores, entonces cualquier (decente) controlador JDBC se registrará en el DriverManager de la siguiente manera

static { 
     DriverManager.registerDriver(new com.example.jdbc.Driver()); 
} 

esta manera la DriverManager puede encontrar el controlador JDBC derecha durante getConnection().

5

Sí. Es un instance initializer. Se ejecuta tan pronto como se crea una instancia de la clase.

+2

¿Entonces la palabra clave estática es opcional? – blackanchorage

+0

entonces, si crea un bloque estático en el código anterior, ¿cuál ejecutará primero el bloque estático o el bloque de inicializador estático? .... ¿puede explicar qué es el inicializador estático? – Hariharbalaji

+1

Definitivamente NO es un inicializador "estático". – BalusC

2

Las llaves inmediatamente dentro de una clase introducen un inicializador de instancia (introducido en Java 1.1). Se tratan de manera muy similar al código para asignar campos escritos como parte de la declaración. Así que los siguientes son equivalentes:

private final Thing x = new Thing(); 

y

private final Thing x; 
{ 
    x = new Thing(); 
} 

El código es ejecutado por los constructores inmediatamente después de llamar a un constructor de la superclase. Por lo tanto, suponiendo que no hay otra inicialización, el código se puede escribir de forma equivalente como parte del constructor:

private final Thing x; 
public MyCLass() { 
    super(); // Often implicit. 
    x = new Thing(); 
} 

Los apoyos en la misma posición precedido de las static de palabras clave y estáticas inicializadores, ejecuta una vez cuando una clase se inicializa, no en una por instancia.

3

En el código anterior, por qué es que la instrucción dada dentro de las llaves ((es decir, "Hai") se imprime antes de que se ejecute el constructor.

Debido a que este es el comportamiento esperado como se describe en la sección 12.5 Creation of New Class Instances de la Java Language Specification :)

Justo antes de una referencia al objeto recién creado se devuelve como el resultado , el constructor indicada es procesados ​​para inicializar el nuevo objeto usando el siguiente procedimiento:

  1. asignar el arg umentos para el constructor a las variables recién creadas del parámetro para esta invocación al constructor .
  2. Si este constructor comienza con una invocación del constructor explícito de otro constructor en la misma clase (usando this), y luego evaluar los argumentos y proceso que constructor invocación recursiva utilizando estos mismos cinco pasos. Si la invocación de ese constructor finaliza abruptamente, entonces este procedimiento finaliza abruptamente para por la misma razón; de lo contrario, continúe con el paso 5.
  3. Este constructor no comienza con un constructor explícito invocación de otro constructor en la misma clase (utilizando this). Si esto es constructor para una clase distinta de Object, a continuación, este constructor se comienzan con una explícita o implícita invocación de un constructor de la superclase (usando super). Evalúe los argumentos y procese esa invocación de constructor de superclase recursivamente utilizando los mismos cinco pasos. Si esa invocación de constructor completa abruptamente, entonces este procedimiento se completa abruptamente por el mismo motivo . De lo contrario, continúe con el paso 4.
  4. Ejecutar los inicializadores de instancia y variables de instancia inicializadores para esta clase, la asignación de los valores de ejemplo inicializadores de variables a las variables de instancia correspondientes, en el orden de izquierda a derecha en el que aparecen textualmente en el código fuente para la clase. Si la ejecución de cualquiera de estos inicializadores resulta en una excepción , entonces no se procesan más inicializadores y este procedimiento finaliza abruptamente con esa misma excepción . De lo contrario, continúe con el paso 5. (En algunos principios implementaciones, el compilador incorrectamente omite el código para inicializar un campo si la expresión de inicialización campo fue una constante expresión cuyo valor era igual a el valor de inicialización por defecto para su tipo.)
  5. Ejecute el resto del cuerpo de este constructor. Si esa ejecución finaliza abruptamente, entonces este procedimiento finaliza abruptamente para el mismo motivo . De lo contrario, este procedimiento se completa normalmente.

Véase la sección 8.6 Instance Initializers para más detalles sobre ... inicializadores de instancia.

Cuestiones relacionadas