IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Collection et Stream Java Discussion :

Initialisation d'un tableau tardive?


Sujet :

Collection et Stream Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    227
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 227
    Points : 77
    Points
    77
    Par défaut Initialisation d'un tableau tardive?
    Bonjour.
    Voici le code que j'ai tapé (en simplifiant. Les objets modele et controleur n'ont pas d'importance):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
     
    class AbstractVue {
     
    	protected AbstractModele modele;
    	protected Controleur controleur;
     
    	//Constructeur
    	public AbstractVue(AbstractModele modele, Controleur controleur) {
    		this.modele = modele;
    		this.controleur = controleur;
    		this.initComposant();
    	}
    	protected abstract void initComposant();
    }
     
     
     
    class AbstractVueSwingAvecJTextField extends AbstractVue {
    	//Constructeur
    	public AbstractVueSwingAvecJTextField(Modele modele, Controleur controleur) {
    		super(modele, controleur);
    	}
     
    	protected void initComposant() {
    		//initialisation de composants (n'agit pas sur l'objet tableau)
    		...
    	}
     
    	...
    }
     
     
     
    class VueSwing1 extends AbstractVueSwingAvecJTextField {
     
    	private String[] tableau={"T1", "T2"};
    	//Constructeur 
     
    	public VueSwing1(Modele modele, Controleur controleur) {
    		super(modele, controleur);
    	}
     
    	protected void initComposant() {
    		super.initComposant();
    		...
    		System.out.println(tableau[0]);
    		...
    	}
    }
    Mais quand je lance la construction de VueSwing1 avec le code this.vue = new VueSwing1(modele, controleur); (les objets modele et controleur n'ont pas d'importance)
    j'ai un nullpointerexception sur l'objet tableau.
    Quand j'exécute le débogueur, le code est bien exécuté comme il faut, sauf la ligne d'initialisation tableau={"T1", "T2"}; qui est exécutée après les méthodes initComposant().
    Je ne comprends pas pourquoi. est-ce que c'est un comportement normal de Java?
    Merci.

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 554
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 554
    Points : 21 615
    Points
    21 615
    Par défaut
    Ceci est un excellent exemple de la grande question :

    "Pourquoi ne doit-on jamais appeler, dans un constructeur, de méthode qui peut être redéfinie par les sous-classes ?"

    Réponse : parce que ça fait ça.

    Citation Envoyé par JCD21 Voir le message
    Je ne comprends pas pourquoi. est-ce que c'est un comportement normal de Java?
    C'est tout à fait normal.
    initComponent() est appelé par le constructeur de la classe mère. Or le constructeur de la classe mère est appelé avant les initialiseurs de la classe fille.

    Or l'initialisation de ce tableau fait partie de l'initialisation de la classe fille.

    Ce ne serait pas un problème si la méthode initComponent(), exposée par la classe mère, ignorait l'existence du tableau, déclaré par la classe fille, et n'y touchait jamais.
    Mais initComponent() peut être redéfinie par la classe fille qui, elle, connaît l'existence du tableau et peut tenter d'y accéder, bien que ses initialiseurs et son constructeur n'aient pas encore commencé et donc que le tableau ne soit pas initialisé.

    Il aurait été préférable de ne pas laisser redéfinir initComponent().
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par thelvin Voir le message

    "Pourquoi ne doit-on jamais appeler, dans un constructeur, de méthode qui peut être redéfinie par les sous-classes ?"
    On ne doit pas, mais on le fait tous, parce que mine de rien ça reste pratique, mais dans ce cas on en tiens compte et on fait gaffe à ça

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 554
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 554
    Points : 21 615
    Points
    21 615
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    On ne doit pas, mais on le fait tous, parce que mine de rien ça reste pratique, mais dans ce cas on en tiens compte et on fait gaffe à ça
    Personnellement j'ai pris l'habitude de les rendre statiques et/ou privées et de ne les laisser redéfinissables que quand c'est bel et bien l'effet voulu, avec documentation lourde.
    Conséquence logique d'Eclipse réglé par défaut pour faire un warning dans ce cas.

    Mais bon.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Personnellement j'ai pris l'habitude de les rendre statiques et/ou privées et de ne les laisser redéfinissables que quand c'est bel et bien l'effet voulu, avec documentation lourde.
    On est d'accord

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    227
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 227
    Points : 77
    Points
    77
    Par défaut
    Donc
    - soit je définis mon tableau dans le code de la méthode initComposant() de la classe VueSwing1 (là ça va pas être pratique car en fait il y a 20 valeurs: est-ce qu'il y a une autre façon que d'écrire tableau[0]="T1"; tableau[1]="T2"... ?), mais ce n'est pas un code très propre?

    - soit j'enlève le this.initComposant(); du constructeur de AbstractVue et je le mets dans le constructeur de VueSwing1, là ça marche? (c'est dommage car j'aurais aimé que tous les constructeurs des vues exécutent initComposant(), mais je peux écrire initComposant() dans tous les constructeurs)

    - soit quoi?

  7. #7
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    option 2 la plus propre, ca permet de garantir l'ordre, ca évite les ecueils des méthodes protégées, et ça évite de rappeler à chacun qu'il faut appeler super.initComponent()

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    227
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 227
    Points : 77
    Points
    77
    Par défaut
    Finalement, j'ai fait l'option 2 et ça marche.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Initialisation d'un tableau à plusieurs dimensions
    Par kinouseb dans le forum Windows Forms
    Réponses: 2
    Dernier message: 07/02/2007, 13h16
  2. Initialisation d'un tableau de pointeurs
    Par tintin72 dans le forum C++
    Réponses: 19
    Dernier message: 19/11/2006, 10h22
  3. Problème d'initialisation d'un tableau
    Par Premium dans le forum C
    Réponses: 13
    Dernier message: 31/05/2006, 14h48
  4. Débutant : initialisation d'un tableau
    Par lebokto dans le forum C++
    Réponses: 7
    Dernier message: 02/11/2005, 15h50
  5. Initialisation d'un tableau de type STRUCT
    Par Axiome dans le forum MFC
    Réponses: 4
    Dernier message: 06/09/2005, 10h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo