Pregunta

Recientemente estuve leyendo algo de Java y encontré algo (¿un idioma?) nuevo para mí: en el programa, las clases con múltiples constructores también incluirían siempre un constructor en blanco. Por ejemplo:

public class Genotype {
  private boolean bits[];
  private int rating;
  private int length;
  private Random random;

  public Genotype() {              //  <= THIS is the bandit, this one right here
    random = new Random();
  }

  /* creates a Random genetoype */
  public Genotype(int length, Random r) {
    random = r;
    this.length = length;
    bits = new boolean[length];

    for(int i=0;i<length;i++) {
        bits[i] =random.nextBoolean();
    }
  }

  /* copy constructor */
  public Genotype(Genotype g,Random r) {
    random = r;
    bits = new boolean[g.length];
    rating = g.rating;
    length = g.length;

    for(int i=0;i<length;i++) {
        bits[i] = g.bits[i];
    }

  }
}

El primer constructor no parece ser un " real " constructor, parece que en todos los casos se utilizará uno de los otros constructores. Entonces, ¿por qué se define ese constructor?

¿Fue útil?

Solución

No estoy seguro de que el código que estaba leyendo fuera de alta calidad (he revisado algunos códigos de bioinformática en el pasado y, lamentablemente, a menudo no están escritos por desarrolladores profesionales). Por ejemplo, ese tercer constructor no es un constructor de copia y, por lo general, hay problemas en este código, por lo que no leería demasiado en él.

El primer constructor es un constructor predeterminado. Solo inicializa el mínimo indispensable y permite a los usuarios configurar el resto con captadores y configuradores. Otros constructores son a menudo " constructores de conveniencia " que ayudan a crear objetos con menos llamadas. Sin embargo, esto a menudo puede llevar a inconsistencias entre los constructores. De hecho, hay investigaciones recientes que muestran que es preferible un constructor predeterminado con llamadas posteriores a los establecedores.

También hay ciertos casos en los que un constructor predeterminado es crítico. Por ejemplo, ciertos marcos como Digestor (utilizados para crear objetos directamente desde XML) usan constructores predeterminados. JavaBeans en general utiliza constructores por defecto, etc.

También, algunas clases heredan de otras clases. es posible que vea un constructor predeterminado cuando la inicialización del objeto principal es " suficientemente buena " ;.

En este caso específico, si ese constructor no estuviera definido, uno tendría que conocer todos los detalles de antemano. Eso no siempre es preferible.

Y, finalmente, algunos IDE generan automáticamente un constructor predeterminado, es posible que quien haya escrito la clase tenga miedo de eliminarlo.

Otros consejos

Es el objeto Serializable ?

  

Para permitir que los subtipos de clases no serializables se serialicen, el subtipo puede asumir la responsabilidad de guardar y restaurar el estado de los campos públicos, protegidos y (si son accesibles) del supertipo del paquete. El subtipo puede asumir esta responsabilidad solo si la clase que extiende tiene un constructor sin argumentos accesible para inicializar el estado de la clase. Es un error declarar una clase serializable si este no es el caso. El error se detectará en tiempo de ejecución.

     

Durante la deserialización, los campos de las clases no serializables se inicializarán utilizando el constructor público o protegido sin argumentos de la clase. Un constructor sin argumentos debe ser accesible para la subclase que se puede serializar. Los campos de las subclases serializables serán restaurados desde la corriente

Sí, acepto el " espacio en blanco " el constructor no siempre debe existir (en mi experiencia, los principiantes a menudo cometen este error), aunque hay casos en los que el constructor en blanco sería suficiente. Sin embargo, si el constructor en blanco viola la invariable de que todos los miembros tienen una instancia correcta después de la construcción , no se debe usar el constructor en blanco. Si el constructor es complicado, es mejor dividir la construcción en varios métodos protegidos / privados. Luego use un método static u otra clase Factory para llamar a los métodos protegidos para la construcción, según sea necesario.

Lo que escribí arriba es el escenario ideal. Sin embargo, los marcos como Spring eliminan la lógica del constructor del código y en algunos archivos de configuración XML. Puede tener funciones de captador y definidor, pero probablemente se evite desde la interfaz, como se describe aquí .

El constructor predeterminado NO es obligatorio.

Si no hay constructores definidos en la clase, el constructor predeterminado (vacío) se creará automáticamente. Si ha proporcionado algún constructor parametrizado, el constructor predeterminado no se creará automáticamente y es mejor que lo cree usted mismo. Los marcos que utilizan la inyección de dependencia y la creación dinámica de proxy en tiempo de ejecución generalmente requieren un constructor predeterminado. Entonces, depende de los casos de uso de la clase que escribas.

El constructor predeterminado no es una buena práctica para la vista funcional. El constructor predeterminado se usa si el objeto tiene una visibilidad global de un método: por ejemplo, desea registrar el estado real de un objeto en un try / catch puedes codificar

MyObejct myObject=null
try{...
}catch(Exception e){
    log.error(myObject);//maybe print null. information?
}

o prefieres

MyObejct myObject=new Object();
try{...
}catch(Exception e){
log.error(myObject);//sure print  myobject.toString, never null. More information
}

?

Otra forma en la que crear un objeto VACÍO no tiene mucha lógica, pero en mi opinión, la incitación a un objeto NULO es perjudicial. Puede leer esta publicación

Eso NO es un constructor de copia. Básicamente quieres constructores vacíos cuando trabajas con algún framework. Siempre habrá un constructor vacío, por supuesto, público o privado, pero al menos le permite mantener el control de cómo se está (o no) la clase de la clase.

Normalmente escribo un constructor que inicializa completamente el objeto; si hay otros, todos lo llaman (...) con los valores predeterminados apropiados.

Un objeto debe estar 100% inicializado y listo para su uso cuando se crea.

Algunos marcos, por ejemplo Hibernate, exigen un constructor sin argumentos. La forma en que chocan con las mejores prácticas me inquieta a veces.

Tener un constructor predeterminado y vacío (en blanco) le impide tener campos finales. Esto conduce a una gran mutabilidad donde a menudo no es necesario.

El patrón de constructor le permite mezclar estos dos estilos y permitir una inicialización más flexible mientras aún tiene inmutabilidad al ocultar un constructor de muchos argumentos detrás de la fábrica.

Para algunas clases de POJO o una clase simple, el constructor predeterminado es útil cuando a veces desea hacer pruebas de unidad en la clase usándolas. No es necesario que se burlen de ellos, puede crear un objeto nuevo con el constructor predeterminado y probar el conjunto de valores y obtener de ellos o pasarlos como un argumento.

Desea crear un constructor en blanco para las clases que extendieron esto clase y como se ha extendido a la clase ... el niño ahora tiene un super que hace referencia a la clase que está por encima de su padre. En el caso de que el hijo no haya especificado super (material) ... el material interno para hacer referencia a los otros constructores para usarlo ahora intentará hacer referencia al constructor vacío.

No estoy seguro de cuál será el error. Ahora estoy codificando mi primera relación de objeto principal y estaba buscando cosas aquí.

Supongo que debo agregar que en el momento en que creas un constructor que no es el vacío, pierdes el vacío predeterminado, así que ahora super (), que es el valor predeterminado en la clase extendida, no tendrá nada a lo que apuntar. Por supuesto, si creó las clases extendidas para cuidar de las súper especificando en qué se deshace de las súper () predeterminadas, entonces elude esto, pero ¿qué pasa si alguien quiere usar su clase y se extiende de ella y no se dio cuenta de que no existe? Un conjunto vacío cuando podrías tener acaba de crear uno.

Esta es mi primera publicación, pero quería entender cómo la entiendo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top