2009-10-18 17 views

Respuesta

15

De acuerdo con el capítulo 12.5 Creation of New Class Instances de la especificación del lenguaje Java:

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

  1. Asignar los argumentos para el constructor de parámetro recién creado variables para este contras tructor invocación.
  2. Si este constructor comienza con una invocación del constructor explícito de otro constructor en la misma clase (con esto), 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 una invocación explícita del constructor de otro constructor en la misma clase (usando esto). Si este constructor es para una clase que no sea Objeto, este constructor comenzará con una invocación explícita o implícita de un constructor de superclase (utilizando super). Evalúe los argumentos y procese esa invocación del constructor de la 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. Ejecutar los inicializadores de instancia y la instancia inicializadores de variables para esta clase, la asignación de los valores de ejemplo inicializadores de variables a las variables de instancia correspondientes, en la en la que aparecen de izquierda a derecha 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.

Así que la diferencia es sólo el paso (paso 4. o el paso 5.) pero el resultado es el mismo.

-3

momento de la construcción. El primero se hace antes de que se ingrese main. La construcción del otro objeto se retrasa hasta que se llame al ctor de SomeClass.

+5

¿Cómo sería el primero hacerse antes principal? No es estático ... – Zed

+0

mi mal ... :(El primer ejemplo crearía SomeObject justo antes de que se ejecute el constructor ... ¿Correcto? – dicroce

+0

La respuesta es igual a @Pascal copiada de JLS ver # 4 y # 5 –

0

En la primera instancia, obj se inicializará antes de ejecutar el constructor. Este es un matiz importante cuando tienes subclases. El orden de los constructores y los bloques de inicialización será:

  1. inicializadores superclase
  2. constructor de la superclase
  3. inicializadores subclase
  4. constructor de la subclase
+1

Esa no es mi interpretación del §12.5 del JLS y no creo que sea verdad. –

+0

Está mal. Javac genera el código en el constructor * después de * una llamada al super constructor. Entiendo que C# es diferente (pero no puedes usar 'this' en tales expresiones). –

2

La única diferencia es en al which step la referencia se inicializa . El efecto final es el mismo.

1

Esto es solo una cuestión de estilo, se compila con el mismo código.

Personalmente tiendo a poner toda inicialización de instancias en constructores, porque eso funciona de manera uniforme para todos los casos.

0

Un aspecto aún no se menciona:

public class SomeClass { 
    SomeObject obj = new SomeObject(); 
    //rest of the code 
} 

inicializará obj a un valor fijo. Pero al inicializar en un constructor, puede hacer que la inicialización dependa de los parámetros del constructor, o (con múltiples constructores) usar expresiones de inicialización completamente diferentes, p.

public class SomeClass { 
    private SomeObject obj; 
    public SomeClass(int length){ 
     obj = new SomeObject(3 * length + 7); 
    } 
    //rest of the code 
} 
Cuestiones relacionadas