2011-08-09 16 views
6

Duplicar posible:
Should I initialize variable within constructor or outside constructorInicialización sobre declaración contra la inicialización de constructores

me preguntaba, que es una mejor práctica y por qué. ¿Debería inicializar los campos de clase en la declaración, o debería hacerlo en el constructor? Dado que es una inicialización simple de una línea.

class Dude 
{ 
    String name = "El duderino"; 

    Dude() { 
     // irrelevant code 
    } 
} 

vs

class Dude 
{ 
    String name; 

    Dude() { 
     name = "El duderino"; 

     // irrelevant code 
    } 
} 

Editar: Soy consciente de las situaciones en las que uno de los estilos se preferirá sobre la otra como en el caso de la ejecución del código de inicialización que podría lanzar una excepción . De lo que estoy hablando aquí son casos en que ambos estilos son absolutamente equivalentes. Ambas formas cumplirían la misma tarea. ¿Qué debería usar entonces?

Respuesta

4

Si el miembro puede única establecerse a través de un acceso (un método "setter"), prefiero el primer estilo. Proporciona una pista de que el valor inicializado es el predeterminado en la construcción.

Si se puede especificar el miembro durante la construcción, generalmente paso el valor predeterminado a un constructor apropiado desde el constructor con menos parámetros. Por ejemplo,

final class Dude { 

    private final String name; 

    Dude() { 
    this("El Duderino"); 
    } 

    Dude(String name) { 
    this.name = name; 
    } 

} 
+0

Esto suena razonable. Pero de lo que estaba hablando son campos que iban a ser inicializados de la misma manera, es decir, los datos recuperados de los constructores no serían utilizados. Como inicializar una Lista interna vacía para almacenar subelementos. ¿Todavía lo inicializarías en el constructor? – amrhassan

+0

@amrhassan - En ese caso, no, yo lo inicializaría cuando se declare, y declararía que es 'final '. – erickson

+0

Puedo ver el motivo por el cual es 'final' en tu ejemplo, pero ¿qué pasa si hay un setter' setName (String name) '... – knownasilya

0

El primero se utiliza generalmente para inicializar la variable estática y se debe usar solo para ese fin.

En este caso, debe usar el segundo método.

Corrija esta respuesta si me equivoco.

+0

el primero funciona bien para ninguno de los campos estáticos. es un azúcar sintáctico para la 2da. – amit

+0

Sí, sé lo que quieres decir. Pero si ha usado C++, sabrá que no hay nada como lo que hizo en el primero para inicializar las variables estáticas y esto se agregó a java para este propósito exacto: inicializar variables estáticas. Por lo tanto, se debe utilizar para el propósito para el que fue hecho. – mtahmed

+0

No veo ninguna razón para reservar el primer estilo para variables estáticas. ¿Puedes proporcionar algún razonamiento? – erickson

0

Lo mejor es declarar variables dentro del constructor en aras de la coherencia. Una variable puede requerir algo como un bucle o una instrucción if-else para inicializarlo, lo que no se puede hacer en la declaración sin colocar la operación dentro de un método.

La excepción a esta regla son las variables estáticas, que deben declararse fuera del constructor.

+0

Podemos usar bloques de inicialización para inicializar campos que, de otro modo, solo se inicializarían dentro de un método o constructor. – emory

0

Las declaraciones de línea única no pueden contener lógica de inicialización compleja.

Si inicializa una variable como:

class AnotherClass 
{ 
    MyClass anObject = new MyClass(); //MyClass() throws a checked exception. 
} 

continuación, usted encontrará que usted no puede proporcionar el valor inicial en la línea única. Tendrá que colocar dicho código en un bloque, que, obviamente, va dentro de un constructor (o en un bloque de inicialización no estática):

El uso de un constructor:

class AnotherClass 
{ 
    MyClass anObject; 

    AnotherClass() 
    { 
     try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/} 
    } 
} 

El uso de un bloque de inicialización:

class AnotherClass 
{ 
    MyClass anObject; 

    { 
     try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/} 
    } 
} 

me parece que este último hace que para el código de menos comprensible, ya que la declaración e inicialización están separados el uno del otro, y la inicialización no se produce en un constructor codificado por el desarrollador (aunque no hay ninguna diferencia en tiempo de ejecución)

Lo mismo ocurre con otras rutinas complejas implicadas en la inicialización de campos.Por ejemplo, si va a inicializar un Array o una Collection y establecer el contenido de la matriz/recogida a un valor predeterminado, entonces usted debe hacerlo dentro de un constructor:

class AnotherClass 
{ 
    Integer[] integers; 

    AnotherClass() 
    { 
     this.integers = new Integer[10]; 
     for(Integer integer: integers) 
     { 
      integer = Integer.MIN_VALUE; 
     } 
    } 
} 
+1

En realidad, también se podría usar un bloque de inicialización aquí, por lo que el constructor no es la única forma posible, incluso en este caso – Voo

+0

Sí, eso podría ser muy confuso. Pero esa es mi opinión. Editaré –