9 votes

Pourquoi pourrait-on aussi utiliser un constructeur vide ?

J'ai récemment lu du Java et je suis tombé sur quelque chose (un idiome?) de nouveau pour moi : dans le programme, les classes avec plusieurs constructeurs incluraient également toujours un constructeur vide. Par exemple :

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

  public Genotype() {              //  <= C'est le bandit, celui-ci ici
    random = new Random();
  }

  /* crée un génotype aléatoire */
  public Genotype(int length, Random r) {
    random = r;
    this.length = length;
    bits = new boolean[length];

    for(int i=0;i

`

Le premier constructeur ne semble pas être un constructeur "réel", il semble que dans tous les cas l'un des autres constructeurs sera utilisé. Alors, pourquoi ce constructeur est-il défini?

`

10voto

Uri Points 50687

Je ne suis pas sûr que le code que vous lisiez était de haute qualité (j'ai examiné quelques codes de bioinformatique dans le passé et il est malheureusement souvent écrit par des développeurs non professionnels). Par exemple, ce troisième constructeur n'est pas un constructeur de copie et en général, il y a des problèmes dans ce code, donc je ne le prendrais pas trop à la lettre.

Le premier constructeur est un constructeur par défaut. Il initialise seulement le strict minimum et permet aux utilisateurs de paramétrer le reste avec des getters et des setters. Les autres constructeurs sont souvent des "constructeurs de commodité" qui aident à créer des objets avec moins d'appels. Cependant, cela peut souvent conduire à des incohérences entre les constructeurs. En fait, il existe des recherches récentes qui montrent qu'un constructeur par défaut avec des appels ultérieurs aux setters est préférable.

Il y a aussi des cas où un constructeur par défaut est essentiel. Par exemple, certains frameworks comme digester (utilisé pour créer des objets directement à partir de XML) utilisent des constructeurs par défaut. Les JavaBeans en général utilisent des constructeurs par défaut, etc.

De plus, certaines classes héritent d'autres classes. Vous pouvez voir un constructeur par défaut lorsque l'initialisation de l'objet parent est "suffisante".

Dans ce cas spécifique, si ce constructeur n'était pas défini, il faudrait connaître tous les détails à l'avance. Ce n'est pas toujours préférable.

Enfin, certains IDE génèrent automatiquement un constructeur par défaut, il est possible que la personne qui a écrit la classe ait eu peur de l'éliminer.

5voto

Chris Nava Points 4048

L'objet est-il Serializable?

Pour permettre aux sous-types de classes non sérialisables d'être sérialisés, le sous-type peut assumer la responsabilité de sauvegarder et de restaurer l'état des champs publics, protégés et (si accessibles) de la classe supérieure. Le sous-type ne peut assumer cette responsabilité que si la classe qu'il étend a un constructeur sans argument accessible pour initialiser l'état de la classe. Il est une erreur de déclarer une classe Serializable si tel n'est pas le cas. L'erreur sera détectée à l'exécution.

Pendant la désérialisation, les champs des classes non sérialisables seront initialisés en utilisant le constructeur public ou protégé sans argument de la classe. Un constructeur sans argument doit être accessible à la sous-classe qui est sérialisable. Les champs des sous-classes sérialisables seront restaurés à partir du flux.

3voto

phaedrus Points 8060

Oui, je suis d'accord que le constructeur \"blank\" ne devrait pas toujours exister (dans mon expérience, les débutants font souvent cette erreur), bien qu'il y ait des cas où un constructeur blank suffirait. Cependant, si le constructeur blank viole l'invariant que tous les membres sont correctement instanciés après la construction, le constructeur blank ne doit pas être utilisé. Si le constructeur est compliqué, il est préférable de diviser la construction en plusieurs méthodes protégées/privées. Ensuite, utilisez une méthode static ou une autre classe Factory pour appeler les méthodes protégées pour la construction, au besoin.

Ce que j'ai écrit ci-dessus est le scénario idéal. Cependant, des frameworks comme spring déplacent la logique du constructeur hors du code et dans certains fichiers de configuration xml. Vous pouvez avoir des fonctions getter et setter, mais elles peuvent probablement être évitées de l'interface, comme décrit ici.

2voto

gedevan Points 929

Le constructeur par défaut n'est PAS obligatoire.

Si aucun constructeur n'est défini dans la classe, alors un constructeur par défaut (vide) sera créé automatiquement. Si vous avez fourni un ou plusieurs constructeurs paramétrés, alors le constructeur par défaut ne sera pas créé automatiquement et il est préférable de le créer vous-même. Les frameworks qui utilisent l'injection de dépendances et la création de proxy dynamique à l'exécution nécessitent généralement un constructeur par défaut. Ainsi, cela dépend des cas d'utilisation de la classe que vous écrivez.

0voto

alepuzio Points 702

Le constructeur par défaut n'est pas une bonne pratique pour la vue fonctionnelle. Le constructeur par défaut est utilisé si l'objet a une visibilité globale dans une méthode: par exemple, vous voulez enregistrer l'état actuel d'un objet dans un try/catch vous pouvez coder

MyObejct myObject=null
try{...
}catch(Exception e){
    log.error(myObject);//peut-être imprimer null. information?
}

ou préférez-vous

MyObejct myObject=new Object();
try{...
}catch(Exception e){
log.error(myObject);//certainement imprimer myobject.toString, jamais null. Plus d'informations
}

?

Une autre façon de créer un objet VIDE n'a pas beaucoup de logique, mais instancier un objet NULL est nuisible à mon avis. Vous pouvez lire ce post

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X