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

avec Java Discussion :

Perte de variable locale


Sujet :

avec Java

  1. #1
    Membre habitué
    Perte de variable locale
    Bonjour à tous,
    J'ai le modèle suivant :
    Livre étends Article

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public class ArticleC  
     { 
         private int reference; 
         private String designation; 
         private double prix;


    La classe Livre possède un champ auteur de type classe Personne :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public class LivreC3 extends ArticleC 
     { 
         private String isbn; 
         private int nbPages; 
         private PersonneC auteur;



    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public class PersonneC  
     { 
         private String nom; 
         private String prenom; 
         private LocalDate date_nais; 
         private ArrayList<ArticleC> oeuvresList;

    et la classe Personne possède une liste oeuvresList qui indique les œuvres de cette personne

    Dans le main qui se trouve dans une autre classe j’instancie des objets Livre de cette façon :
    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
     
    public class Exo4 {
    public static void main(String[] args) {
    		ArticleC a,a1;
    		LivreC3 l;
    		DvdC3 d;
            PersonneC p,p1;
     
    l=new LivreC3();
            l.setReference(001);
            l.setDesignation("Le Pigeon0");
            l.setPrix(20.54);
            l.setIsbn("1245879215");
            l.setNbPages(254);
            l.setAuteur(p=new PersonneC("Zone3","Eric3",LocalDate.of(1983, 12,11),l.getReference(),l.getDesignation(),l.getPrix()));

    Le constructeur de Personne :
    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
     
     public PersonneC(String n,String p,LocalDate d,int ref,String des,double prx) //ajoute ref et des dans liste des oeuvres
         { 
             this.nom=n; 
             this.prenom=p; 
             this.date_nais=d;
             ArticleC oeuvre;
             oeuvre=new ArticleC();
             oeuvre.setReference(ref); 
             oeuvre.setDesignation(des); 
             oeuvre.setPrix(prx);
             oeuvresList=new ArrayList<>();
             oeuvresList.add(oeuvre);           
     
         }

    permet de créer un nouvel Auteur et d'ajouter une œuvre dans sa liste d’œuvre.
    Dans la classe Livre j'ai un champ auteur de type classe Personne, la ligne
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    l.setAuteur(p=new PersonneC("Zone3","Eric3",LocalDate.of(1983, 12,11),l.getReference(),l.getDesignation(),l.getPrix()));

    dans le main permet d'associer un nom d'auteur pour un Livre, la fonction setAuteur se décline comme ça dans la classe Livre :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public void setAuteur(PersonneC auteur) { 
            	              this.auteur = auteur; 
            	             ArrayList<ArticleC> lst; 
            	             lst=auteur.getoeuvresList();
            	          if (!lst.contains(this)) 
            	            { 
            	                lst.add(this); 
            	            } 
            	        }

    si l'oeuvre crée n'est pas connue dans la liste des oeuvres de cette personne l'oeuvre est rajoutée dans la liste; c'est la fonction getoeuvresList qui renvoit l'info :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public ArrayList<ArticleC> getoeuvresList()  
         { 
           return oeuvresList; 
         }

    LE problème que j'ai est que la valeur de lst se perd quand je reviens dans le main du coup l'oeuvre est toujours rajoutée.
    Comment faire si quelq'un a une idée Merci

  2. #2
    Modérateur

    Hello,

    Citation Envoyé par xeron33 Voir le message
    LE problème que j'ai est que la valeur de lst se perd quand je reviens dans le main
    Pas spécialement, non.

    Citation Envoyé par xeron33 Voir le message
    du coup l'oeuvre est toujours rajoutée.
    Non, ça c'est juste parce que l'oeuvre n'est jamais la même donc jamais connue. A chaque fois tu fais un new pour créer l'oeuvre, soit dans le constructeur de Personne, soit dans main(). En tout cas, c'est toujours une oeuvre différente, donc elle n'est jamais trouvée et elle est toujours ajoutée. Normal.


    Citation Envoyé par xeron33 Voir le message
    Comment faire si quelq'un a une idée Merci
    Le plus simple, ce serait de construire les Personnes comme s'il était possible qu'une personne n'ait produit aucune oeuvre. Par exemple, je me rappelle qu'à ma naissance, je n'avais encore publié aucun de mes romans à succès. Il faudrait pouvoir représenter ça.

    Du coup, le constructeur de Personne ne prendrait pas d'oeuvre en paramètre, et construirait une liste d'oeuvre, vide. Avec zéro oeuvre dedans.

    Ensuite, il faudra ajouter une nouvelle méthode Personne.ajouterOeuvre(), pour ajouter une oeuvre au répertoire d'une personne, quand cette oeuvre commence à exister.

    Il te restera à décider si c'est Livre.setAuteur() qui appelle Personne.ajouterOeuvre() ou si c'est Personne.ajouterOeuvre() qui appelle Livre.setAuteur(). Peu importe du moment que c'est l'un et pas l'autre.

    Conséquence de la chose, l'oeuvre n'est pas déjà dans la liste au moment où on voudrait l'ajouter. C'est un fait certain, et il n'y a donc pas besoin de vérifier. On l'ajoute, point final.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre habitué
    Réponse à thelvin :


    ********************************************************
    Merci pour ton aide.

    Du coup, le constructeur de Personne ne prendrait pas d'oeuvre en paramètre, et construirait une liste d'oeuvre, vide. Avec zéro oeuvre dedans.
    Du coup, je l'ai écris comme ça :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public PersonneC(String n,String p,LocalDate d,ArrayList oeuvresList) 
         { 
             this.nom=n; 
             this.prenom=p; 
             this.date_nais=d; 
             oeuvresList=new ArrayList<> ();
         }

    et la méthode SetAuteur de Personne :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public void setAuteur(PersonneC auteur) { 
            	 int ref;
            	 String des;
            	 double prix; 
            	 ref=this.getReference();
            	 des=this.getDesignation();
            	 prix=this.getPrix();            
            	 auteur.AjouterOeuvre(ref, des, prix);
           }

    la méthode AjouterOeuvre :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public void AjouterOeuvre(int ref,String des,double prx)
         {
        	 ArticleC oeuvre;
             oeuvre=new ArticleC();
             oeuvre.setReference(ref); 
             oeuvre.setDesignation(des); 
             oeuvre.setPrix(prx);
             oeuvresList=new ArrayList<>();
             oeuvresList.add(oeuvre); 
         }

    dans le main :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     ArrayList<LivreC3> l_Livre;
     
    l=new LivreC3();
            l.setReference(001);
            l.setDesignation("Le Pigeon0");
            l.setPrix(20.54);
            l.setIsbn("1245879215");
            l.setNbPages(254);
            l.setAuteur(p=new PersonneC("Zone3","Eric3",LocalDate.of(1983, 12,11),l_Livre=new ArrayList()));

    Maintenant j'ai n'ai plus qu'un Livre dans la liste :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
     
    System.out.println("il y a  " + p.getoeuvresList().size() + " Livre(s) dans la liste");
            System.out.println("Livre  " + p.getoeuvresList());

    résultat :
    il y a 1 Livre(s) dans la liste
    Livre [Référence Article : 1 Désignation Article : Le Pigeon0 Prix Article : 20.54 €], mais je voudrais savoir comment je peux faire pour appeler une Personne connue et lui affecter un nouveau livre ou essayer de lui affecter un livre déjà écrit ou pas, en d'autres termes comment "rappeler" un objet en java qui vient d'être construit?(new), car en effet comme tu dis

    A chaque fois tu fais un new pour créer l'oeuvre, soit dans le constructeur de Personne, soit dans main(). En tout cas, c'est toujours une oeuvre différente, donc elle n'est jamais trouvée et elle est toujours ajoutée. Normal.
    je voudrais pouvoir réutiliser de suite un objet p :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    p=new PersonneC()

    Merci si tu as des infos la dessus.

  4. #4
    Membre régulier
    Salut,
    Je me permets d'entrer dans la conversation

    Citation Envoyé par xeron33 Voir le message


    Du coup, je l'ai écris comme ça :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public PersonneC(String n,String p,LocalDate d,ArrayList oeuvresList) 
         { 
             this.nom=n; 
             this.prenom=p; 
             this.date_nais=d; 
             oeuvresList=new ArrayList<> ();
         }

    Je ne pense pas que thelvin voyait les choses comme ça ^^.
    Si j'ai bien compris, une personne à une liste de livres dont elle est auteure. Cela veut dire que dans ta class, tu as une variable de class "private ArrayList<ArticleC> oeuvresList;" qui est instancié dans ton constructeur. Tu n'as pas besoin de passer une ArrayList en paramètre de ton constructeur car là tu instancies une liste quelconque mais pas celle de la personne. Tu dois faire référence à celle de ta class.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public PersonneC(String n,String p,LocalDate d) 
         { 
             this.nom=n; 
             this.prenom=p; 
             this.date_nais=d; 
             this.oeuvresList=new ArrayList<> ();
         }


    Citation Envoyé par xeron33 Voir le message

    et la méthode SetAuteur de Personne :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public void setAuteur(PersonneC auteur) { 
            	 int ref;
            	 String des;
            	 double prix; 
            	 ref=this.getReference();
            	 des=this.getDesignation();
            	 prix=this.getPrix();            
            	 auteur.AjouterOeuvre(ref, des, prix);
           }

    Si tu penses en objet, une personne ne peut être l'auteure de lui-même. Cette méthode à part contre toute ça place dans le class Livre mais pas Personne.

    Citation Envoyé par xeron33 Voir le message

    la méthode AjouterOeuvre :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public void AjouterOeuvre(int ref,String des,double prx)
         {
        	 ArticleC oeuvre;
             oeuvre=new ArticleC();
             oeuvre.setReference(ref); 
             oeuvre.setDesignation(des); 
             oeuvre.setPrix(prx);
             oeuvresList=new ArrayList<>();
             oeuvresList.add(oeuvre); 
         }

    Pourquoi ta méthode "AjouterOeuvre" réinstancie ta liste ? Si tu laisses ainsi cela veut dire qu'a chaque fois que tu ajoutes une oeuvre à ton auteur, il perd toutes les anciennes œuvres qu'il avait. Sachant que tu as instancié ta liste dans le constructeur tu n'as plus besoin de la faire ici et tu n'auras plus besoin de le faire nulle part (à moins que tu fasses une méthode qui réinitialise toutes les oeuvres de l'auteur).

    Citation Envoyé par xeron33 Voir le message

    je voudrais pouvoir réutiliser de suite un objet p :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    p=new PersonneC()

    Merci si tu as des infos la dessus.
    Si j'ai bien compris, tu voudrais avoir une liste de personnes à qui tu puisses affecter un livre ? Si c'est le cas, il suffit d'instancier plusieurs personnes au début de ton code puis soit tu laisse comme tel sois tu les stockes d'une manière ou d'une autre (dans une liste par exemple). Ensuite, tu as juste à choisir une personne et utiliser sa méthode "affectuerLivre".

    Je ne sais pas si j'ai été assez clair et si j'ai bien compris ton problème.
    J'espère t'avoir aidé en tout cas .

  5. #5
    Membre habitué
    Réponse à Badshade23
    quote
    Bonjour, depuis le temps, je sais pas si tu es toujours interessé par le sujet, mais puisque j'ai trouvé une solution je me devais de te la transmettre pour te remercier de ton intervention :

    Je ne pense pas que thelvin voyait les choses comme ça ^^.
    Si j'ai bien compris, une personne à une liste de livres dont elle est auteure. Cela veut dire que dans ta class, tu as une variable de class "private ArrayList<ArticleC> oeuvresList;" qui est instancié dans ton constructeur. Tu n'as pas besoin de passer une ArrayList en paramètre de ton constructeur car là tu instancies une liste quelconque mais pas celle de la personne. Tu dois faire référence à celle de ta class.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public PersonneC(String n,String p,LocalDate d) 
         { 
             this.nom=n; 
             this.prenom=p; 
             this.date_nais=d; 
             this.oeuvresList=new ArrayList<> ();

    Pour çà OK



    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    et la méthode SetAuteur de Personne :
     
    public void setAuteur(PersonneC auteur) { 
            	 int ref;
            	 String des;
            	 double prix; 
            	 ref=this.getReference();
            	 des=this.getDesignation();
            	 prix=this.getPrix();            
            	 auteur.AjouterOeuvre(ref, des, prix);
           }
     
    Si tu penses en objet, une personne ne peut être l'auteure de lui-même. Cette méthode à part contre toute ça place dans le class Livre mais pas Personne

    Oui erreur de ma part quand j'avais posté la question


    la méthode AjouterOeuvre :

    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
     
     
     
     
    public void AjouterOeuvre(int ref,String des,double prx)
         {
        	 ArticleC oeuvre;
             oeuvre=new ArticleC();
             oeuvre.setReference(ref); 
             oeuvre.setDesignation(des); 
             oeuvre.setPrix(prx);
             oeuvresList=new ArrayList<>();
             oeuvresList.add(oeuvre); 
         }
     
    Pourquoi ta méthode "AjouterOeuvre" réinstancie ta liste ? Si tu laisses ainsi cela veut dire qu'a chaque fois que tu ajoutes une oeuvre à ton auteur, il perd toutes les anciennes œuvres qu'il avait. Sachant que tu as instancié ta liste dans le constructeur tu n'as plus besoin de la faire ici et tu n'auras plus besoin de le faire nulle part (à moins que tu fasses une méthode qui réinitialise toutes les oeuvres de l'auteur).

    Oui en effet tu as raison


    Moi même ==>"je voudrais pouvoir réutiliser de suite un objet p :"


    p=new PersonneC()

    Merci si tu as des infos la dessus.
    "
    Si j'ai bien compris, tu voudrais avoir une liste de personnes à qui tu puisses affecter un livre ? Si c'est le cas, il suffit d'instancier plusieurs personnes au début de ton code puis soit tu laisse comme tel sois tu les stockes d'une manière ou d'une autre (dans une liste par exemple). Ensuite, tu as juste à choisir une personne et utiliser sa méthode "affectuerLivre".
    Pour ce faire j'ai créé une liste de classe PersList dans la classe main qui me permet d'avoir une historique de toutes les variables p, j'ai aussi redéfini les méthodes equals et hashCode de la classe Personne testant p sur le nom :
    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
     
    public boolean equals(Object obj) 
              { 
                   PersonneC p;   
                   // vérification si obj est null ou référence une instance 
                   // d’une autre classe 
                   if (obj ==null || obj.getClass()!=this.getClass()) 
                   { 
                        return false; 
                   } 
                   else                   
                   { 
                	   p=(PersonneC) obj;
                        // vérification des critères d’égalité sur 
                        // - Nom 
                        if (p.getNom().equals(getNom()))  //si paramètre obj ou p egal à Liste 
                        { 
                             return true; 
                        } 
                        else 
                        { 
                             return false; 
                        } 
                   } 
              }
     
              public int hashCode() 
              { 
                   return ((this.getNom()).hashCode());          		          
              }

    La méthode setAuteur de la classe Livre a elle aussi été revue en utilisant la liste PersList qui permet si auteur inconnu de l'ajouter dans cette liste, sinon d'ajouter toutes les oeuvres de l'Auteur.Ensuite itéreration de tous les Articles de l'auteur si l'article passé en paramètre n'est pas dans la liste des oeuvres de cet auteur alors je le rajoute (AjouterOuevre) puis mise à jour de la liste PersList
    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
     
    public void setAuteur(PersonneC auteur) {
            	 this.auteur=auteur;
            	 int ref;
            	 String des;
            	 double prix; 
            	 ref=this.getReference();
            	 des=this.getDesignation();
            	 prix=this.getPrix(); 
            	 boolean diff=false;
            	 Iterator<PersonneC> itP; // ici historique des Personnes et rajout si necessaire des Personnes
                 itP=Exo4.PersList.iterator();
                 if(Exo4.PersList.size()==0)
                 {
                	 diff=true;              
                 }
                 PersonneC p;
                 while (itP.hasNext())             	
                 {
                   p=itP.next();	 
                   if(!p.equals(auteur))
                   {
                	   diff=true;
                   }
                     else
                   {
                       auteur.getoeuvresList().addAll(p.getoeuvresList());	 
                	   diff=false;
                   }
                 }
                 if(diff)
                 {
                	 Exo4.PersList.add(auteur);
                	 diff=false;
                 }   
                   else
                 {
                	  // ne pas remettre listArticle.addAll(p.getoeuvresList()); 
     
                 }
                		 Iterator<ArticleC> itP1; //Lste des Articles si inconnu dans les oeuvres de auteur alors AjouterOeuvre
                		 itP1=auteur.getoeuvresList().iterator();          		
                	     ArticleC a;           	            		 
                		 if(auteur.getoeuvresList().size()==0)
                		 {
                			 diff=true;
                		 }           		 
                		 while (itP1.hasNext())
                		 {
                			 a=itP1.next();
                		 if(a.equals(this.getReference()))
                    		 {
                			     diff=false; 
                    		 }
                			   else
                			   {
                				   diff=true;
                			   }
                			// itP1.next();
                		 }
                		 if(diff)
                         {
                			 this.auteur.AjouterOeuvre(ref, des, prix);
                			 Exo4.PersList.remove(auteur); //mise à jour PersList
                			 Exo4.PersList.add(auteur);          			 		
                         }
     
                 }

    et la méthode AjouterOeuvre

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     public void AjouterOeuvre(int ref,String des,double prx)
         {
        	 ArticleC oeuvre;
             oeuvre=new ArticleC();
             oeuvre.setReference(ref); 
             oeuvre.setDesignation(des); 
             oeuvre.setPrix(prx);
             oeuvresList.add(oeuvre);    
         }

    Maintenant ça fonctionne comme je le voulais.
    Si tu as des remarques ne te gêne pas
    Merci encore
    A+