2009-07-25 12 views
5

Cuál es la diferencia entre estos dos métodos de inicialización de los observadores ArrayList. O cualquier otro tipo para ese asunto. ¿Es uno más rápido que el otro? O me estoy perdiendo algún otro beneficio aquí.Java: ¿Cuál es la diferencia entre estos métodos de construcción

class Publisher implements Observerable 
{ 
    private ArrayList observers = new ArrayList(); 
} 

class Publisher implements Observerable 
{ 
    private ArrayList observers; 

    public Publisher() 
    { 
     observers = new ArrayList(); 
    } 
} 

Respuesta

13

Son equivalentes. De hecho, si compila los dos verá que generan exactamente el mismo código de bytes:

Publisher(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: aload_0 
    5: new  #2; //class java/util/ArrayList 
    8: dup 
    9: invokespecial #3; //Method java/util/ArrayList."<init>":()V 
    12: putfield  #4; //Field observers:Ljava/util/ArrayList; 
    15: return  
} 

Dado que son el mismo código, no claro que no puede haber ninguna diferencia de velocidad :)

Tenga en cuenta que en C# no son equivalentes: en C# el inicializador para observers se ejecutaría antes de la llamada del constructor base; en Java, realmente son lo mismo.

Cuál usted utiliza es una cuestión de gusto. Si tiene varios constructores diferentes que inicializan una variable de la misma manera, tendría sentido usar la primera forma. Por otro lado, generalmente es una buena idea si tienes varios constructores para tratar de hacer que la mayoría de ellos llame a un constructor "central" que hace el trabajo real.

+1

de Jon Skeet atacan de nuevo –

+1

¿Usted también consigue el mismo código de bytes con un inicializador ejemplo? Yo diría que la respuesta es sí. –

+1

@mmyers: Sí, exactamente lo mismo otra vez. –

4

son iguales, pero: la diferencia es que en el último ejemplo, se obtiene la ventaja de ser capaz de hacer la lógica de inicialización más avanzada: el manejo de errores, etc.

1

En realidad no hay ninguna diferencia. Una ventaja de la primera manera es que si tiene múltiples constructores, no necesita recordar inicializar observers en todos ellos.

En el segundo ejemplo, puede ser más flexible, si desea ajustar el valor en función de los argumentos del constructor.

2

La única diferencia real está en el orden de las operaciones. Los campos que se inicializan en su declaración se evalúan antes de llamar al constructor de la clase. Los campos que se inicializan en una subclase de esta manera se evaluarán después de que se complete el constructor del super pero antes de que se invoque el constructor de la subclase.

Considere el siguiente ejemplo:

tengo una clase de prueba:

public class Tester { 
    Tester (String msg) { 
     System.out.println(this + ":" + msg); 

    } 
} 

tengo una superclase:

public class Test { 

    protected Tester t1 = new Tester("super init block"); 

    Test (String constructorMsg) { 
    new Tester(constructorMsg); 
    } 
} 

y tengo una subclase:

Public class TestSub extends Test { 

    private Tester t2 = new Tester("sub init block"); 

    TestSub(String constructorMsg) { 
     super(constructorMsg); 
     new TTester("sub constructor"); 
    } 

} 

En mi main método, se crea una instancia de TestSub:

public static void main(String[] args) { 
    new TestSub("super constructor"); 

} 

los resultados son los siguientes: ediciones

[email protected]:super init block 
[email protected]:super constructor 
[email protected]:sub init block 
[email protected]:sub constructor 
+0

Todo lo cual dice, para el ejemplo que se muestra en la pregunta, no hay * diferencia * - porque el constructor en la segunda versión solo consiste en la misma llamada que en el inicializador de campo en la primera versión. Es importante destacar que el inicializador de campo se llama * después * del superconstructor, no antes. –

Cuestiones relacionadas