[java] probleme avec un passage d'argument...

probleme avec un passage d'argument... [java] - Java - Programmation

Marsh Posté le 02-12-2003 à 16:04:53    

Bonjour a tous et toutes,
j'ai un petit soucis avec une de mes methodes, dont voici le code :
 

Code :
  1. private void constructionRec(Vector ePart, HashMap tabChemCentre, BankWayList chemPart) {
  2. chemPart.removeAll(); // initialisation (=supprime tous les elements du vecteur de chemPart)
  3. if(ePart.size() == 1) // cas d'arret
  4.     for(int i = 0; i < ePart.size(); i++) {
  5.  Entity entite = (Entity)ePart.get(i); // pour toute entite 'entite' de 'ePart'
  6.  BankWayList bl = (BankWayList)tabChemCentre.get(entite.getName());
  7.  chemPart = bl;
  8.  // (1) ICI QUAND ON AFFICHE "chemPart" IL CONTIENT BIEN CE QU'IL Y A DANS "bl"
  9.     } // for i
  10. else
  11.     for(int j = 0; j < ePart.size(); j++) {
  12.  Entity e = (Entity)ePart.get(j); // pour toute entite 'e' de 'ePart'
  13.  BankWayList chemSousPart = new BankWayList();
  14.  Vector ePartMoinsE = new Vector();
  15.  ePartMoinsE = (Vector)ePart.clone();
  16.  ePartMoinsE.removeElementAt(j); // ePartMoinsE = ePart\{e}
  17.  constructionRec(ePartMoinsE, tabChemCentre, chemSousPart);
  18.  // (2) ICI IL AFFICHE LA VARIABLE "chemSousPart" COMME ETANT VIDE !!!
  19.     } // for j
  20.     } // constructionRec


 
Mon probleme est le suivant :  
- a l'endroit (1) de la methode je met dans la variable "chemPart" ce qu'il y a dans "bl". Si je fais un affichage, on voit bien que "chemPart" a bien pris la valeur de "bl".
- par contre, lorsque j'affiche en (2) le contenu de ma variable   "chemSousPart" que j'avais passee en argument, alors la je me rencontre qu'elle ne contient rien.
 
Je pense que cela vient du fait que certains objets ne pointent pas sur la meme chose mais je n'en suis pas sûr.
Je pense que c'est une erreur bête mais je n'arrive pas a la trouver !
Quelqu'un pourrait-il m'aider ?
 
Baba


Message édité par babthefox2002 le 02-12-2003 à 16:06:47
Reply

Marsh Posté le 02-12-2003 à 16:04:53   

Reply

Marsh Posté le 02-12-2003 à 16:10:49    

quand tu fais  
        chemPart = bl;  
c'est juste la variable locale chemPart que tu modifies, pas la variable qui a été utilisée lors de l'appel de la méthode, ni l'objet que ces deux variables pointent ...


Message édité par benou le 02-12-2003 à 16:12:34

---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 02-12-2003 à 16:15:57    

comment puis-je faire pour modifier la variable que je passe en argument alors ??

Reply

Marsh Posté le 02-12-2003 à 16:19:12    

mais en fait dans la suite de ma methode, dans le "else" je fais  
 

Code :
  1. chemPart = chemSousPart;


 
Et la je me rends compte que chemSousPart est vide, alors qu'il contenait qqchose dans la recursive precedante !

Reply

Marsh Posté le 02-12-2003 à 16:28:57    

babthefox2002 a écrit :

mais en fait dans la suite de ma methode, dans le "else" je fais  
 

Code :
  1. chemPart = chemSousPart;


 
Et la je me rends compte que chemSousPart est vide, alors qu'il contenait qqchose dans la recursive precedante !


bha oui ...
 
exemple :  

Code :
  1. public void changePersonne(Personne p) {
  2.    p = new Personne("Tata" );
  3. }


Code :
  1. Personne p1 = new Personne("Toto" );
  2. changePersonne(p1);
  3. // ici p vaut toujours toto


parce que dans le méthode changePersonne, tu créés un nouvel objet que tu attache à la variable locale p. Mais la variable p1, elle n'est pas modifiée.
 
 
T'as 4 solutions :  
1) soit tu modifies l'objet (an appelant des méthodes dessus), 2) soit ta méthode devient une fonction et elle retourne la valeur de l'objet que tu aura créé dedans et ce sera à toi d'affecter cet objet à ta variable.
3) soit tu englobes ton objet dans un autre objet qui te servira de conteneur.
4) tu revois ton algo parce qu'il est bancale
 
tu connais les pointeurs ou pas ? ce sera peut être plus simple de t'expliquer comme ca ...


Message édité par benou le 02-12-2003 à 16:30:02

---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 02-12-2003 à 16:41:33    

oui je connais les pointeurs, mais normalement je croyais que quand  tu passais un objet 'toto' en parametre d'une methode personne(), le parametre correspondant a 'toto' dans personne() pointait toujours sur la meme chose que 'toto', sauf dans le cas ou dans personne on fait un truc genre :
objet tata = (le parametre correspondant a 'toto')
ou la 'tata' est une variable locale de personne().

Reply

Marsh Posté le 02-12-2003 à 18:53:27    

:sweat:  
bon ....
 
 
si tu connais les pointeurs, on va attaquer par ce bout là.
Quand tu fais  

Code :
  1. Personne p = new Personne("toto" );


Ca créé un objet Personne en mémoire. L'adresse mémoire de cet objet est stocké dans la variable locale p.  
 
Donc p ne contient que l'adresse mémoire, rien d'autre. C'est un pointeur vers l'objet.
 
Quand tu appelles une méthode en java et que tu passes en arguments des objets, c'est le pointeur que tu passes : la veleur de la variable, c'est à dire l'adresse mémoire. C'est un passage par valeur !
 
Donc, une fois dans ta méhode, la variable (le paramêtre) est locale. C'est un nouvelle variable qui contient la même valeur (l'adresse mémoire de l'objet) que la variable qui a été utilisé dans l'appel de la méthode : c'est uen copie de la valeur de la variable.
 
Donc si dans ta méthode tu fais  

Code :
  1. leParam = new Personne("tutu" );


la variable locale va prendre la valeur de l'adresse mémoire du nouvel objet. Mais c'est uniquement la variable locale qui est affectée, pas la variable qui avait été utilisé pour faire l'apelle de la méthode : elle, elle garde sa valeur originale.
 
capiché ?


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 02-12-2003 à 18:59:41    

Ok merci, je vais corriger mon erreur...
Je ne savais pas que ca changeait de valeur que localement... Merci pour l'explication.

Reply

Marsh Posté le 02-12-2003 à 23:55:54    

euh
benou je voudrais pas lancer un débat à cette heure-ci, mais j'pense que t'as tout faux... :/
 
 
plus de détails dans qques minutes.
(faire du java sous vi, j'ai connu plus excitant)


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 02-12-2003 à 23:59:04    

voila.

Code :
  1. -bash-2.05b$ cat Test.java
  2. public class Test {
  3. private int x = 3;
  4. public Test() {
  5. }
  6. public Test(int i) {
  7.    this.x = i;
  8. }
  9. public void setTest(Test t) {
  10.   this.x = t.getX();
  11.   t.setX(123);
  12. }
  13. public int getX() { return this.x; }
  14. public void setX(int i) { this.x = i; }
  15. public String toString() { return "Test[x="+x+"]"; }
  16. public static void main(String[] args) {
  17.   Test t1 = new Test(44);
  18.   Test t2 = new Test();
  19.   System.out.println("t1="+t1);
  20.   System.out.println("t2="+t2);
  21.   t2.setTest(t1);
  22.   System.out.println("t1="+t1);
  23.   System.out.println("t2="+t2);
  24. }
  25. }
  26. -bash-2.05b$ /usr/local/java/bin/javac Test.java
  27. -bash-2.05b$ /usr/local/java/bin/java Test
  28. t1=Test[x=44]
  29. t2=Test[x=3]
  30. t1=Test[x=123]
  31. t2=Test[x=44]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 02-12-2003 à 23:59:04   

Reply

Marsh Posté le 03-12-2003 à 00:00:57    

on passe donc bien par réference à une methode, et la reference n'est pas "localisée" à la méthode appelée.
 
sauf pour les types primitifs (forcément) et les immutables (ça c taiche qui l'a dit; ça me parait logique mais bon, je répond de rien)


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 03-12-2003 à 00:01:39    

the real moins moins a écrit :

euh
benou je voudrais pas lancer un débat à cette heure-ci, mais j'pense que t'as tout faux... :/


 :heink:


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 03-12-2003 à 00:05:44    

voir la suite.....


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 03-12-2003 à 00:08:21    


 [:wam]  
en quoi ca va à l'encontre de ce que j'ai dit ??
 

the real moins moins a écrit :

on passe donc bien par réference à une methode.


bien sûr qu'on passe un objet par référence. C'est pas comme en C++ où une copie de l'objet est faite à chaque appel de méthode ! Mais si on parle du pointeur (puisqu'une référence est un pointeur), c'est la valeur du pointeur (adresse méméoire) qui est passée. et ce passage est fait par copie !

the real moins moins a écrit :

sauf pour les types primitifs (forcément) et les immutables (ça c taiche qui l'a dit; ça me parait logique mais bon, je répond de rien)


 [:wam]  
pour les types primitifs, c'est comme pour les objets ! c'est toujours du passage par copie de la valeur de la variable. Si c'est un type primitif, la valeur de la variable est le type lui même => c'est une simple copie. Quand c'est une référence c'est pareil : c'est une copie de cette référénce qui devient une 2e référence vers le même objet, mais c'est pas en écrasant la valeur de cette référence (en faisant une bête affectation) que tu vas modifier la 1ere référence...
 
quand au fait d'immaginer que le passage des paramêtres se fait différement si c'est un type immuable [:kiki]  
Comment il peut le savoir java quand c'est un type immuable ??
 
 
franchement, ca me déçoit que tu puisses penser que je me trompe sur un truc aussi basique que ca :(


Message édité par benou le 03-12-2003 à 00:16:03

---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 03-12-2003 à 00:09:09    

the real moins moins a écrit :

et la reference n'est pas "localisée" à la méthode appelée.


bien sûr qu'elle l'est !
 
en quoi ton exemple montre qu'elle ne l'est pas ?


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 03-12-2003 à 00:13:46    

démonstrattion :  
 

Code :
  1. package test;
  2. class Toto {
  3. private String s;
  4.  public Toto(String s) {
  5.   this.s = s;
  6.  }
  7.  public String toString() {
  8.  return this.s;
  9. }
  10. }
  11. public class TestRef {
  12. public static void testCpyRef(Toto ref) {
  13.  ref = new Toto("objet local" );
  14. }
  15. public static void main(String[] args) {
  16.  Toto t = new Toto("t1" );
  17.  testCpyRef(t);
  18.  System.out.println(t);
  19. }
  20. }


Citation :

t1


 
[:spamafote]
 
je suis étonné que tu puisses te faireavoir sur ce genre de trucs  :heink:  
Ou bien on s'est mal compris ?


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 03-12-2003 à 00:18:14    

benou a écrit :


quand au fait d'immaginer que le passage des paramêtres se fait différement si c'est un type immuable [:kiki] comment il peut le savoir java que c'est un type immuable ??


Euh baaaaaa... fais un test tout con, genre une méthode qui prend une String en paramètre, qui la modifie et qui l'affiche. Tiens, de tête et sans compiler :

Code :
  1. public class machin tout ça
  2. {
  3. public static joulieMethode(String s)
  4. {
  5.   s += "graou";
  6.   System.out.println(s);
  7. }
  8. public static void main(String[] args)
  9. {
  10.   String hop = "hop";
  11.   joulieMethode(hop);
  12.   System.out.println(hop);
  13. }
  14. }


T'auras :

Citation :


hopgraou
hop


joulieMethode a modifié localement la variable et pis c'est tout. En revanche, fais pareil avec une ArrayList (en lui rajoutant des éléments, par exemple) et ton ArrayList initiale sera bien modifiée.


---------------
Everyone thinks of changing the world, but no one thinks of changing himself  |  It is the peculiar quality of a fool to perceive the faults of others and to forget his own  |  Early clumsiness is not a verdict, it’s an essential ingredient.
Reply

Marsh Posté le 03-12-2003 à 00:19:42    

benou a écrit :

démonstrattion :  
Ou bien on s'est mal compris ?  


Ca doit être ça, alors [:ddr555]
Passke d'après ce que j'en ai lu, tu semblais dire que le passage de paramètre en Java c'était du passage par valeur et non par référence :o


---------------
Everyone thinks of changing the world, but no one thinks of changing himself  |  It is the peculiar quality of a fool to perceive the faults of others and to forget his own  |  Early clumsiness is not a verdict, it’s an essential ingredient.
Reply

Marsh Posté le 03-12-2003 à 00:22:38    

Taiche a écrit :


Ca doit être ça, alors [:ddr555]
Passke d'après ce que j'en ai lu, tu semblais dire que le passage de paramètre en Java c'était du passage par valeur et non par référence :o


la valeur du pointeur !!


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 03-12-2003 à 00:25:13    

Taiche a écrit :

joulieMethode a modifié localement la variable et pis c'est tout. En revanche, fais pareil avec une ArrayList (en lui rajoutant des éléments, par exemple) et ton ArrayList initiale sera bien modifiée.


[:totoz]
 
mais tu confonds tout !!!
 
quand tu fais un += d'une string et quand tu fais un add dans une arraylist ca a rien à voir !!!
 
Un += d'une String tu créée un nouvel objet String que tu affectes à la référence locale => ca n'a aucun effet en dehors de la méthode.
Un add d'une arraylist c'est un appel qui va modifier l'objet pointé par la référence => ca a un effet en dehors de la méthode
 
 
qu'est ce que vous me faites là ???? [:fear]


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 03-12-2003 à 00:27:11    

[:core 666]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 03-12-2003 à 00:27:33    

Reply

Marsh Posté le 03-12-2003 à 00:27:53    

bah oui d'autant que les String de jawa sont constants  :heink:


---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
Reply

Marsh Posté le 03-12-2003 à 00:29:10    

SchnapsMann a écrit :

bah oui d'autant que les String de jawa sont constants  :heink:  


tu réponds "bha oui" à quoi ???
 
et qu'est ce que tu appelles constant ? par rapprt à immuable, je veux dire ...


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 03-12-2003 à 00:29:53    

benou a écrit :


tu réponds "bha oui" à quoi ???
 
et qu'est ce que tu appelles constant ? par rapprt à immuable, je veux dire ...


 
oui c'est bien ça que je voulais dire, je parlais pas des références hein  :(
 
donc += sur un String, c'est sur que ça change pas le String  :o


Message édité par schnapsmann le 03-12-2003 à 00:30:29

---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
Reply

Marsh Posté le 03-12-2003 à 00:30:01    

benou a écrit :


 [:wam]  
en quoi ca va à l'encontre de ce que j'ai dit ??
 


 
ben, je lis ça

Citation :


Donc si dans ta méthode tu fais  
 
Code :
 
  leParam = new Personne("tutu" );
 
la variable locale va prendre la valeur de l'adresse mémoire du nouvel objet. Mais c'est uniquement la variable locale qui est affectée, pas la variable qui avait été utilisé pour faire l'apelle de la méthode : elle, elle garde sa valeur originale.  


j'essaie et je vois ce qu'il me semblait: que la variable passée n'est pas locale à la methode...
ou alors y'a un truc qui m'echapp


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 03-12-2003 à 00:30:46    

SchnapsMann a écrit :


oui c'est bien ça que je voulais dire, je parlais pas des références hein  :(  


j'ai toujours pas compris ce que tu disais :pt1cable:


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 03-12-2003 à 00:33:55    

au fait benou, le prend pas pour toi hein :o
je suis en train de faire un autre test qui là me montre que t'as raison mais y'a tjs un truc qui m'échappe.


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 03-12-2003 à 00:34:51    

the real moins moins a écrit :

la variable passée n'est pas locale à la methode...
ou alors y'a un truc qui m'echapp


a ce moment, quand je parlais de "la variale" je parlais de la référence, pas de l'objet qu'elle pointait.
 
regarde dans l'exemple de code que j'ai donné  :

Code :
  1. public class TestRef {
  2. public static void testCpyRef(Toto ref) {
  3. ref = new Toto("objet local" );
  4. }
  5. public static void main(String[] args) {
  6. Toto t = new Toto("t1" );
  7. testCpyRef(t);
  8. System.out.println(t);
  9. }
  10. }

 
la variable "t" n'est pas affectée par l'appel de testCpyRef() parce que la variable "ref" de testCpyRef() est une copie de la valeur de la variable "t" => si tu changes la valeur de "ref" ca ne change pas la valeur de "t" : c'est 2 variables différentes [:spamafote]


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 03-12-2003 à 00:35:55    

the real moins moins a écrit :

au fait benou, le prend pas pour toi hein :o
je suis en train de faire un autre test qui là me montre que t'as raison mais y'a tjs un truc qui m'échappe.


 
nan nan t'inquiètes ... mais j'arrive pas à croire que ca vous étonne  [:mlc2]  
 
c'est quoi qui t'échappe ?


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 03-12-2003 à 00:36:17    

et oui, les passages d'arguments de java sont toujours fait par valeur, fou non  [:naughty]
 
gros rapel pour les cancres du fond:
 
en c++ :
void foo(int a); // par valeur
void bar(inr& a); // par référence
 
en java seul le premier cas est géré  :whistle:  
 


Message édité par schnapsmann le 03-12-2003 à 00:37:48

---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
Reply

Marsh Posté le 03-12-2003 à 00:36:19    

Citation :


-bash-2.05b$ cat Test2.java
public class Test2 {
 private int x = 3;
 public Test2() {
 }
 public Test2(int i) {
   this.x = i;
 }
 public void setTest(Test2 t) {
  this.x = t.getX();
  t = new Test2(666);
 }
 public int getX() { return this.x; }
 public String toString() { return "Test2[x="+x+"]"; }
 
 public static void main(String[] args) {
  Test2 t1 = new Test2(44);
  Test2 t2 = new Test2();
  System.out.println("t1="+t1);
  System.out.println("t2="+t2);
  t2.setTest(t1);
  System.out.println("t1="+t1);
  System.out.println("t2="+t2);
 
 }
}
-bash-2.05b$ /usr/local/java/bin/java Test2
t1=Test2[x=44]
t2=Test2[x=3]
t1=Test2[x=44]
t2=Test2[x=44]


 
et là "benou à raison".
ben c'est super con, mais je suis pas sur de piger pourquoi dans mon 1er exemple, l'objet sur lequel pointe ma reference est modifié par ma methode setText, alors que dans le 2e la nouvelle instance semble locale à cette foutue méthode, alors que la reference vient du dehors...


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 03-12-2003 à 00:37:09    

SchnapsMann a écrit :

et oui, les passages d'arguments de java sont toujours fait par valeur, fou non  [:naughty]  

ha non [:aloy]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 03-12-2003 à 00:38:40    


 
nain porte quoi  :o  
 
remarque je connais pas java 1.5, peut être est-ce une nouveauté :??:


---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
Reply

Marsh Posté le 03-12-2003 à 00:40:09    

on parle de passage par reference en java quand meme, merde, arretez de remettre en doute tout ce que je crois connaitre maintenant :o


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 03-12-2003 à 00:41:20    

the real moins moins a écrit :

on parle de passage par reference en java quand meme, merde, arretez de remettre en doute tout ce que je crois connaitre maintenant :o


 
En java, tu passes une référence par valeur en argument d'une méthode. C'est pas pareil que de passer une variable par référence en argument  :fou:


Message édité par schnapsmann le 03-12-2003 à 00:44:55

---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
Reply

Marsh Posté le 03-12-2003 à 00:45:46    

benou a écrit :


la valeur du pointeur !!


Bin putain, tu crois que le gars de base il a bien pigé ta phrase ?  
J'te cite :

Citation :

Quand tu appelles une méthode en java et que tu passes en arguments des objets, c'est le pointeur que tu passes : la veleur de la variable, c'est à dire l'adresse mémoire. C'est un passage par valeur !


Et après tu gueules qu'on mélange tout [:kiki]

benou a écrit :


[:totoz]
 
mais tu confonds tout !!!


(la preuve [:ddr555])
OK, bin chu d'accord que mon += était pas du tout judicieux. Faisons un .replace('h', 'x') à la place [:spamafote]
 
Si on est déjà 2 à pas tout piger c'que tu racontes (p'têt 3 avec SchnapsMann, j'sais pas), c'est p'têt qu'y a un problème dans la formulation, non ? [:ddr555]


---------------
Everyone thinks of changing the world, but no one thinks of changing himself  |  It is the peculiar quality of a fool to perceive the faults of others and to forget his own  |  Early clumsiness is not a verdict, it’s an essential ingredient.
Reply

Marsh Posté le 03-12-2003 à 00:46:57    

SchnapsMann a écrit :

void foo(int a); // par valeur
void bar(inr& a); // par référence
 
en java seul le premier cas est géré  :whistle:


nan mais là tu prend le cas d'un type primitif, c'est pas ce qu'il y a mieux comme exemple :o
 

SchnapsMann a écrit :

remarque je connais pas java 1.5, peut être est-ce une nouveauté :??:  


nan, mais n'importe quoi ! c'est impossible de changer un truc comme ca !


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 03-12-2003 à 00:47:43    

the real moins moins a écrit :

on parle de passage par reference en java quand meme, merde, arretez de remettre en doute tout ce que je crois connaitre maintenant :o


ouais dans le cas des objets, mais dire "passage par référence" revient au même que de dire "passage par valeur des pointeurs" [:spamafote]


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 03-12-2003 à 00:47:52    

C'est super, personne pige rien à ce que racontent les autres [:ddr555]
 
Bon ba moi j'm'en vais, il pue la mort ce topic :o


---------------
Everyone thinks of changing the world, but no one thinks of changing himself  |  It is the peculiar quality of a fool to perceive the faults of others and to forget his own  |  Early clumsiness is not a verdict, it’s an essential ingredient.
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed