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

Langage Java Discussion :

Passage par reference


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Avatar de Deadpool
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    1 312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 1 312
    Par défaut
    Bon après quelque recherche sur développez à ce sujet, j'ai trouvé ceci

    http://bruce-eckel.developpez.com/li...&page=0#00.005

    Et finalement je suis d'accord avec ceci :

    Ceci nous amène à discuter terminologie, ce qui est toujours bon dans un débat. Le sens de l'expression « passage par valeur » dépend de la perception qu'on a du fonctionnement du programme. Le sens général est qu'on récupère une copie locale de ce qu'on passe, mais cela est tempéré par notre façon de penser à propos de ce qu'on passe. Deux camps bien distincts s'affrontent quant au sens de « passage par valeur » :

    Java passe tout par valeur. Quand on passe un scalaire à une méthode, on obtient une copie distincte de ce scalaire. Quand on passe une référence à une méthode, on obtient une copie de la référence. Ainsi, tous les passages d'arguments se font par valeur. Bien sûr, cela suppose qu'on raisonne en terme de références, mais Java a justement été conçu afin de vous permettre d'ignorer (la plupart du temps) que vous travaillez avec une référence. C'est à dire qu'il permet d'assimiler la référence à « l'objet », car il la déréférence automatiquement lorsqu'on fait un appel à une méthode.
    Java passe les scalaires par valeur (pas de contestations sur ce point), mais les objets sont passés par référence. La référence est considérée comme un alias sur l'objet ; on ne pense donc pas passer une référence, mais on se dit plutôt « je passe l'objet ». Comme on n'obtient pas une copie locale de l'objet quand il est passé à une méthode, il est clair que les objets ne sont pas passés par valeur. Sun semble plutôt soutenir ce point de vue, puisque l'un des mot-clefs « réservés mais non implémentés » est byvalue (bien que rien ne précise si ce mot-clef verra le jour).
    Donc en gros tout dépend de la perception qu'on en a.

    Désolé de vous avoir pris la tête.

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Descent
    Désolé de vous avoir pris la tête.
    Au contraire c'est bien de le préciser

    En effet cela peut être trompeur pour ceux qui viennent du C++ où le passage par référence est différent et peut prendre une part importante de la conception d'une application (Cf la FAQ C++ sur les références).

    a++

  3. #3
    Membre Expert

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 301
    Par défaut
    Hello,

    selon moi, tout est passé par valeur en java...

    quand on écrit:
    on passe la valeur "5" à la méthode... normal

    et quand on écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Object o = new Object();
    foo(o);
    on passe aussi la valeur de "o" à la méthode "foo" ... mais comme "o" est une référence, sa valeur vaut en fait un emplacement mémoire genre "0x10b62c9", et c'est cela qu'on lui passe en paramètre.

    logique non ?

    c'est d'ailleurs la même chose avec le "==":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if(4 == 5) // compare les valeurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if(o1 == o2) // compare les valeurs des références, renvoie true si et seulement si o1 et o2 référencent le même objet (même valeur = même adresse mémoire = même objet)

  4. #4
    Membre Expert
    Avatar de viena
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    1 071
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 1 071
    Par défaut
    Pill : ça se passe bien comme ça. et ça s'appele un passage par référence. La preuve en est :
    pour des objets java non immuables (des classes que vous avez créé par exemple), si on passe un objet à une methode et qu'on travaille sur l'objet, en sortant de la méthode, les modifications sont concervées. Faites le test et vous verrez

  5. #5
    Membre Expert

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 301
    Par défaut
    oui, mais il ne s'agit que d'une conséquence du fait que les paramètres sont passés par valeur, et les objets gérés par référence

  6. #6
    Membre Expert
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Par défaut
    Citation Envoyé par Descent
    Edit, tiens le message auquel j'ai répondu à disparu!
    Oui, j'avoue, j'avais lu ton post en diagonale, et j'ai retiré le mien (qui n'apportait rien) le plus vite possible, mais pas assez ...
    "Le bon ni le mauvais ne me feraient de peine si si si je savais que j'en aurais l'étrenne." B.V.
    Non au langage SMS ! Je ne répondrai pas aux questions techniques par MP.
    Eclipse : News, FAQ, Cours, Livres, Blogs.Et moi.

  7. #7
    Membre éprouvé
    Avatar de Deadpool
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    1 312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 1 312
    Par défaut
    Citation Envoyé par Pill_S
    oui, mais il ne s'agit que d'une conséquence du fait que les paramètres sont passés par valeur, et les objets gérés par référence
    Exactement, dans la méthode on obtient une copie du contenu de la variable, qui est une référence, ce qui permet d'altérer l'objet (s'il est altérable).

    Citation Envoyé par xavlours
    Oui, j'avoue, j'avais lu ton post en diagonale, et j'ai retiré le mien (qui n'apportait rien) le plus vite possible, mais pas assez ...
    Ca m'arrive souvent aussi!

  8. #8
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    509
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 509
    Par défaut
    Citation Envoyé par Pill_S
    oui, mais il ne s'agit que d'une conséquence du fait que les paramètres sont passés par valeur, et les objets gérés par référence
    Moi perso je suis de l'avis de Viena , mais bon c'est juste une question de point , je crois que l'essentiel c'est qui'on sache a peu pres comment ca marche

    Mais quand je vois :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     
    public void foo(Object o){
    ...
    }
    je vois une methode foo qui prend en parametre un Object et dans la mesure ou l'object passé en parametre n'est pas une copie de l'original il s'agit d'un passage par reference.
    La meme syntaxe en C++ pour un objet créé statiquement provoque la copie de celui ci, et un passage par valeur , alors qu'en java on a le meme objet et non une copie (ou un clone).

  9. #9
    Expert confirmé


    Profil pro
    Inscrit en
    Mai 2003
    Messages
    3 240
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 3 240
    Par défaut
    Juste pour completer ce débat, je voudrais rajouter un exemple, montrant que tout est bien un passage par valeur et non par référence.

    Essayez ceci:
    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
     
    class Test {
      private String display;
      public Test(String value) {
        this.display = value;
      }
      public String toString() {
        return display;
      }
    }
    public class Main {    
      public static void foo(Object obj){
        obj = new Test("objet2");
        System.out.println("foo "+obj);  
      } 
      public static void main(String[] args) {
        Object object1 = new Test("objet1");
        System.out.println(object1);
        foo(object1);
        System.out.println(object1);
      }
    }
    Si c'était vraiment un passage par référence, on aurait ceci:
    objet1
    foo objet2
    objet2
    Mais comme c'est un passage par valeur, on obtient
    objet1
    foo objet2
    objet1
    J'espère que jusqu'ici vous avez suivi.

    Maintenant, pour compliquer un peu plus, il faut savoir que lorsqu'on ne manipule pas des primitives en Java, on ne manipule pas non plus des objets. Ni des références à des objets, comme pourrait le penser un programmeur C++). Mais on manipule des pointeurs à des objets. Et lorsqu'on "passe un objet" à une méthode, on ne passe pas l'objet ni sa référence, mais on passe la valeur du pointeur à l'objet. Grande nuance.

    Je vais citer ci-dessous quelques extraits de l'excellent livre "Au coeur de Java 2" Notion fondamentales JDK 5 Volume 1.

    Page 119
    De nombreuses personne pensent à tort que les variables objets de Java se comportent comme les références en C++.
    Mais en C++, il n'y a pas de référence nlles et les références ne peuvent être affectées. Il faut plutôt penser aux variables objet de Java comme aux pointeurs sur objets de C++. Par exemple,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Date birthday;// en Java
    est en fait identique à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Date* birthday; //en C++
    Lorsqu'on fait cette association, tout redevient clair. Bien entendu, un pointeur Date* n'est pas initialisé tant que l'on n'appelle pas new. La syntaxe est presque la même en C++ et en Java:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Date* birthday = new Date(); // C++
    (C'est moi qui ai mis en gras à tort)


    Et la méthode Java suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void method(Date birthday); // en Java
    serait en fait équivalente à ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void method(Date* birthday); // en pseudo C++
    et non à ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void method(Date& birthday); // en C++
    ni à ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void method(Date*& birthday); // en pseudo C++
    -------------------------------

    Page 64
    Les programmeurs C++ sont souvent stupéfaits lorsqu'ils rencontrent des chaines Java pour la première fois, car ils considèrent les chaines comme des tableaux de caractères
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char greeting[] = "Hello";
    La comparaison n'est pas bonne; une chaine Java ressemble davantage à un pointeur char*;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char* greeting = "Hello";
    -------------------------------

    Page 98
    Un tableau Java est assez différent d'un tableau C/C++ dans la pile (stack). Il peut cependant être comparé à un pointeur sur un tableau alloué dans le tas (segment heap de la mémoire). C'est à dire que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int[] a =  new int[100]; //en Java
    n'est pas la même chose que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int[] a =  new int[100]; //en C++
    mais plutot à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int* a =  new int[100]; //en C++

  10. #10
    Membre éprouvé
    Avatar de Deadpool
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    1 312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 1 312
    Par défaut
    Merci pour cette explication!

  11. #11
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 302
    Billets dans le blog
    2
    Par défaut
    Mais alors concrètement, comment fait-on pour faire l'équivalent d'un passage de paramètre de fonction par référence en c++, sur un type primitif en java?

    Exemple concret, comment faire en sorte que le code suivant affiche "a=10"?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class Test{
        public static void f( int a ) {
    		a = 10;
    	}
     
        public static void main(String[] args) {
            int a = 0;
            f(a);
            System.out.print("a=");
            System.out.print(a);
        }
    }

  12. #12
    Membre Expert
    Avatar de CheryBen
    Inscrit en
    Mai 2005
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 599
    Par défaut
    Tu sors un vieux sujet du placard

    Ce que tu demandes est impossible tel quel avec les types primitifs.
    Il y a 2 solutions :
    Ta fonction f renvoi un int et dans le main tu fais a = f(a)
    Tu travailles avec un objet Integer plutôt qu'un int.

  13. #13
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 302
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par CheryBen Voir le message
    Tu sors un vieux sujet du placard
    Vi je suis désolé Mais je pensais que ce serait mieux que d'en créer un nouveau parce que quand j'ai fait la recherche sur ce sujet j'ai eu 3000 résultats et ça fait déjà beaucoup non?
    tu veux que je crée un nouveau?

    Citation Envoyé par CheryBen Voir le message
    Tu travailles avec un objet Integer plutôt qu'un int.
    Ben je viens de tester ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class HelloWord {
    	public static void g( Integer a ){
    		a=10;
    	}
     
        public static void main(String[] args) {
        	Integer a=0;
        	g(a);
            System.out.print( "number = " + a );
            System.out.println();
        }
    }
    et la sortie reste obstinément "number = 0";

    J'ai bien l'impression que ce n'est pas possible en fait, tout simplement.
    Je sais qu'en C# c'est possible avec un mot-clé, ref il me semble. En python ça ne semble pas non plus possible...

  14. #14
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par CheryBen Voir le message
    Tu travailles avec un objet Integer plutôt qu'un int.
    Faux : Integer est une classe immutable et ses données ne pourront pas être changé...


    Il faudrait donc utiliser une classe mutable contenant un int avec ses getter/setter (il n'y a rien de tel en standard).


    Mais cela dépend surtout de ce que tu veux faire avec cela : on ne traduit pas un code C++ en Java ligne par ligne... les philosophies sont différentes !

    a++

  15. #15
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 302
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Mais cela dépend surtout de ce que tu veux faire avec cela : on ne traduit pas un code C++ en Java ligne par ligne... les philosophies sont différentes !
    Oui je sais bien, c'est juste une question "philosophique" que je me pose. En fait, en ce moment j'ai des soucis (en c++) avec des problèmes de gestion de mémoire, j'aimerai comprendre comment les différents langages gèrent le passage de paramètre.

    Merci pour vos réponse

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. [DLL]Erreur de link quand passage par reference
    Par Yeti_in dans le forum C++
    Réponses: 2
    Dernier message: 19/11/2008, 02h47
  2. [debutant(e)]passage par reference
    Par kass28 dans le forum Débuter
    Réponses: 4
    Dernier message: 27/07/2007, 17h56
  3. Probleme d'un passage par reference.
    Par mego dans le forum Langage
    Réponses: 4
    Dernier message: 19/04/2007, 16h41
  4. Probleme sur le passage par reference
    Par schnito dans le forum Langage
    Réponses: 10
    Dernier message: 02/02/2006, 16h50
  5. [VB6]Passage par référence d'une prop. d'objet à une fct
    Par -gYs- dans le forum VB 6 et antérieur
    Réponses: 15
    Dernier message: 02/09/2002, 08h55

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