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

avec Java Discussion :

Pass-by-value ou Pass-by-reference ?


Sujet :

avec Java

  1. #1
    Membre averti
    Homme Profil pro
    Reconversion
    Inscrit en
    Novembre 2018
    Messages
    502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Reconversion
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2018
    Messages : 502
    Points : 300
    Points
    300
    Par défaut Pass-by-value ou Pass-by-reference ?
    Bonjour,

    Je travaille sur le concept de by-pass-value, et j'ai cru comprendre qu'assigner une variable de type objet ou primitive en paramètre d'une méthode dans un caller ne modifiait pas la variable en question. N'étant peut-être pas clair, voici un exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public static void inversValue(int x, int y) { 
    		int c= x;
    		x=y;
    		y=c;
    	} 
     
    	public static void main(String[] args) { //caller
    		int a = 1;
    		int b = 2;
    		inversValue(a, b);//On passe des variables en paramètre dont les valeurs ne seront pas affectés grace au principe du pass-by-value
    		System.out.println(a);
    		System.out.println(b);	// pas de soucis on récupère nos int initiaux
    	}

    Je réfléchis sur ce problème depuis quelques temps sans comprendre pourquoi StringBuiler s2 renvoie "s2b" et non pas "s2". s2 possède une valeur dans la méthode work() qui ne devrait pas impacter le retour du caller non ? Est-ce dû au fait que la classe StringBuilder est mutable ?

    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 static StringBuilder work(StringBuilder a, StringBuilder b) {
    		a = new StringBuilder("a");    
    		b.append("b");   
    		return a;  
    		} 
     
    	public static void main(String[] args) {
    		StringBuilder s1 = new StringBuilder("s1"); 
    		StringBuilder s2 = new StringBuilder("s2");    
    		StringBuilder s3 = work(s1, s2);    
    		System.out.println("s1 = " + s1);//renvoie s1
    		System.out.println("s2 = " + s2);//renvoie s2b
    		} 
     
     
    	}

    Merci

  2. #2
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Il faut voir les paramètres de 2 manières :
    1- type primitif : la valeur source est passé à la méthode cible
    2- type Object : la référence de l'objet est passé à la méthode cible

    Dans le cas 1, effectivement, il n'y au pas d'impact sur les instances souces.
    Dans le cas 2, comme tu passes l'adresse de la variable, il y a bien un impact sur s2 (Ta variable "b" à la même adresse que "s2")
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre averti
    Homme Profil pro
    Reconversion
    Inscrit en
    Novembre 2018
    Messages
    502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Reconversion
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2018
    Messages : 502
    Points : 300
    Points
    300
    Par défaut
    Merci pour ta réponse

    Mais dans ce cas là, je peux également dire que "s1" possède la même adresse que "StringBuilder a". De ce fait, je pourrais déduire que System.out.println(a) retourne "s1", ce qui n'est pas le cas. C'est ça que je ne comprends pas...

  4. #4
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Ce qui est un peu compliqué c'est de comprendre que tout est passé par valeur (primitif ou objet), la différence est que pour l'objet, la "valeur" est l'adresse de l'objet.
    Donc, dans ton cas, tu passes l'adresse de s1 à ta fonction qui la récupère via le paramètre "a".
    Ensuite, tu affectes à "a" l'adresse d'un nouveau StringBuilder, donc maintenant, dans ta fonction, a "pointe" sur autre chose qu'en arrivant.
    Du coup, dans ta méthode appelante, rien n'a changé pour "s1" qui "pointe" toujours sur le même objet contenant la valeur "s1".
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre averti
    Homme Profil pro
    Reconversion
    Inscrit en
    Novembre 2018
    Messages
    502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Reconversion
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2018
    Messages : 502
    Points : 300
    Points
    300
    Par défaut
    Je crois peut-être avoir compris. En fait "s2" et b pointent en effet sur le même objet, et du coup comme on appelle une méthode via la référence du StringBuilder sans réassigner le résultat dans un autre objet, ça modifie explicitement le retour de s2.

    A contrario pour s1, où il n'y a pas d'appel de méthode sur le StringBuilder a en paramètre. Bon j'avoue que c'est confus mais çà ira mieux demain

    Merci pour ton aide

    Du coup j'ai rajouté un schéma pour y voir plus clair et essayer de résumer la situation

    Nom : Sans titre.png
Affichages : 250
Taille : 34,0 Ko

  6. #6
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Pour simplifier au maximum, on aurait
    (dans main)

    [pour s1 = new StringBuilder("s1")]
    -> création en mémoire de la chaîne de caractères "s1"
    -> création en mémoire d'une variable 'StringBuilder' nommée 's1'
    -> utilisation de l'objet 's1' pour ajouter la valeur de la chaîne de caractères "s1"

    [pour s2 = new StringBuilder("s2")]
    -> création en mémoire de la chaîne de caractères "s2"
    -> création en mémoire d'une variable 'StringBuilder' nommée 's2'
    -> utilisation de l'objet 's2' pour ajouter la valeur de la chaîne de caractères "s2"

    [pour s3 = work(s1, s2)]

    (dans la méthode work)
    -> création en mémoire d'une variable 'StringBuilder' nommée 'a'
    -> affectation de l'adresse de la variable 's1' à 'a'
    -> création en mémoire d'une variable 'StringBuilder' nommée 'b'
    -> affectation de l'adresse de la variable 's2' à 'b'
    -> création en mémoire de la chaîne de caractères "a"
    -> création en mémoire d'une variable 'StringBuilder' nommée 'x'
    -> utilisation de l'objet 'x' pour ajouter la chaîne de caractères "a"
    -> affection de l'adresse de 'x' à 'a' (jusque là, 'a' pointait sur 's1')
    -> création en mémoire de la chaîne de caractères "b"
    -> utilisation de l'objet 'b' pour ajouter la chaîne de caractères "b" (b référence s2 et manipule donc la même chose)

    (retour dans main avec l'adresse de l'objet 'StringBuilder' nommée 'a')
    -> création en mémoire d'une variable 'StringBuilder' nommée 's3'
    -> affectation à l'objet 's3' de l'adresse de la variable 'StringBuilder' du retour de la méthode work ('s3' pointe maintenant sur l'adresse de l'objet 'StringBuilder' nommé 'a')
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre averti
    Homme Profil pro
    Reconversion
    Inscrit en
    Novembre 2018
    Messages
    502
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Reconversion
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2018
    Messages : 502
    Points : 300
    Points
    300
    Par défaut
    Merci pour ta réponse très complète, j'ai compris

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 23/06/2019, 14h43
  2. Pass by reference
    Par Retrokiller069 dans le forum Android
    Réponses: 4
    Dernier message: 15/03/2012, 09h18
  3. [Joomla!] Chronoforms: Deprecated: Assigning the return value of new by reference is deprecated
    Par sitws dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 26/11/2011, 15h21
  4. Warning: Call-time pass-by-reference has been deprecated
    Par Poseidon62 dans le forum Langage
    Réponses: 8
    Dernier message: 16/10/2011, 16h03
  5. Réponses: 7
    Dernier message: 03/06/2009, 10h08

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