¿Debo inicializar la variable dentro del constructor o constructor externo

Cuando uso Java según mi conocimiento de C ++, me encanta inicializar la variable de la siguiente manera.

public class ME { private int i; public ME() { this.i = 100; } } 

Después de algún tiempo, cambio el hábito a

 public class ME { private int i = 100; public ME() { } } 

Me encontré con el código fuente de otros, algunos están utilizando la primera convención, otros están utilizando la segunda convención.

¿Puedo saber qué convención recomiendan todos, y por qué?

Encuentro el segundo estilo (statement + inicialización de una vez) superior. Razones:

  • Deja en claro de un vistazo cómo se inicializa la variable. Normalmente, cuando lee un progtwig y encuentra una variable, primero va a su statement (a menudo automática en IDE). Con el estilo 2, verá el valor predeterminado de inmediato. Con el estilo 1, también debes mirar al constructor.
  • Si tiene más de un constructor, no tiene que repetir las inicializaciones (y no puede olvidarlas).

Por supuesto, si el valor de inicialización es diferente en diferentes constructores (o incluso calculado en el constructor), debe hacerlo en el constructor.

Tiendo a usar el segundo para evitar un constructor complicado (o uno inútil), también realmente no considero esto como una inicialización (incluso si es una inicialización), sino más como dar un valor predeterminado.

Por ejemplo, en su segundo fragmento, puede eliminar el constructor y tener un código más claro.

Tengo la práctica (hábito) de casi siempre inicializar en el contructor por dos razones, una en mi opinión se agrega a readablitiy (limpiador), y dos hay más control lógico en el constructor que en una línea. Incluso si inicialmente la variable de instancia no requiere lógica, tenerla en el constructor le da más flexibilidad para agregar lógica en el futuro si es necesario.

En cuanto a la preocupación mencionada anteriormente sobre constructores múltiples, eso se resuelve fácilmente teniendo un constructor sin argumentos que inicializa todas las variables de instancia que se inician de la misma manera para todos los constructores y luego cada constructor llama a this () en la primera línea. Eso resuelve sus problemas de reduncancia.

El único problema que veo con el primer método es si está planeando agregar más constructores. Entonces estarás repitiendo el código y la capacidad de mantenimiento sufrirá.

Si se inicializa en la parte superior o en el constructor no hace mucha diferencia. Pero en algunos casos, la inicialización en el constructor tiene sentido.

 class String { char[] arr/*=char [20]*/; //Here initializing char[] over here will not make sense. String() { this.arr=new char[0]; } String(char[] arr) { this.arr=arr; } } 

De modo que dependiendo de la situación, en algún momento deberá inicializar en la parte superior y, a veces, en un constructor.

FYI otras opciones para la inicialización sin usar un constructor:

 class Foo { int i; static int k; //instance initializer block { //run's every time a new object is created i=20; } //static initializer block static{ //run's only one time when the class is loaded k=18; } } 

Recomiendo inicializar variables en constructores. Es por eso que existen: para garantizar que sus objetos estén construidos (inicializados) correctamente.

De cualquier forma funcionará, y es una cuestión de estilo, pero prefiero los constructores para la inicialización de miembros.

Una cosa, independientemente de cómo inicialice el campo, el uso del calificador final , si es posible, garantizará la visibilidad del valor del campo en un entorno de subprocesos múltiples.

Creo que ambos son correctos en cuanto a la progtwigción,

Pero creo que su primera opción es más correcta de forma orientada a objetos, porque en el constructor es cuando se crea el objeto, y es cuando la variable debe inicializarse.

Creo que es la convención “por el libro”, pero está abierta a discusión.

Wikipedia

Ambas opciones pueden ser correctas dependiendo de tu situación.

Un ejemplo muy simple sería: si tiene múltiples constructores, todos inicializan la variable de la misma manera (int x = 2 para cada uno de ellos). Tiene sentido inicializar la variable en la statement para evitar la redundancia.

También tiene sentido considerar las variables finales en tal situación. Si conoce el valor que tendrá una variable final en la statement, tiene sentido inicializarla fuera de los constructores. Sin embargo, si desea que los usuarios de su clase inicialicen la variable final a través de un constructor, demore la inicialización hasta el constructor.

Puede depender de lo que esté inicializando, por ejemplo, no puede usar la inicialización de campo si se trata de una excepción marcada. Por ejemplo, lo siguiente:

 public class Foo { FileInputStream fis = new FileInputStream("/tmp"); // throws FileNotFoundException } 

Causará un error en tiempo de comstackción a menos que también incluya un constructor que declare esa excepción marcada, o extienda una superclase que sí lo hace, por ejemplo:

 public Foo() throws FileNotFoundException {} 

Yo diría que depende del valor predeterminado . Por ejemplo

 public Bar { ArrayList foos; } 

Haría una new ArrayList fuera del constructor, si siempre asumo que los foos no pueden ser nulos. Si Bar es un objeto válido, sin importar si foos es nulo o no, lo pondría en el constructor.

Puede estar en desacuerdo y decir que es el trabajo de los constructores poner el objeto en un estado válido. Sin embargo, si claramente todos los constructores deberían hacer exactamente lo mismo (inicializar los foos ), ¿por qué duplicar ese código?