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 :

Passage par référence en java


Sujet :

avec Java

  1. #1
    Membre régulier Avatar de psycho_xn
    Inscrit en
    Mars 2007
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 250
    Points : 96
    Points
    96
    Par défaut Passage par référence en java
    Bonjour,
    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 class c_test {
     
        public c_test() {
        }
     
        public void function1(Integer v){
            v +=1;
            System.out.println("function1...........   "+v+"  ....................");
        }
     
        public void function2(Integer v){
            v +=10;
            System.out.println("function2...........   "+v+"  ....................");
        }
     
     
        public static void main(String[] args){
            c_test C = new c_test();
     
            Integer v;
            v=0;
     
            System.out.println("1 = "+v);
            C.function1(v);
            System.out.println("2 = "+v);
            C.function2(v);
            System.out.println("3 = "+v);
        }
    }
    ceci me donne le résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    1 = 0
    function1...........   1  ....................
    2 = 0
    function2...........   10  ....................
    3 = 0
    je chercher à faire un passage par référence à la variable v, qu'est-ce qui est erroné dans mon code qui fait que ceci ne marche pas ??

    Merci bcp
    il n'y a pas de réussite facile, ni d'échec définitif

  2. #2
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 562
    Points : 15 493
    Points
    15 493
    Par défaut
    Le problème viens du fait que Integer n'est pas un type primitif, mais un objet immuable : il n'existe aucune méthode permettant de modifier sa valeur.

    Jusqu'en java 1.4, on ne pouvait pas faire le moindre calcul avec les objets.

    Depuis java 1.5 et l'arrivée de l'autoBoxing/autoUnboxing, les Objets représentant un type(Integer/Byte/Long...) sont automatiquement convertis en leur type primitif équivalent, mais ce n'est jamais que du sucre syntaxique : v étant immuable, si tu lui affecte une valeur, il est créé un nouvel objet.

    Par exemple dans ton code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    v += 1
    // équivaut en fait a un 
    v = new Integer(v.intValue()++);
    L'objet auquel v faisait référence n'est donc pas modifié.

  3. #3
    Membre régulier Avatar de psycho_xn
    Inscrit en
    Mars 2007
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 250
    Points : 96
    Points
    96
    Par défaut
    Citation Envoyé par Uther Voir le message
    Le problème viens du fait que Integer n'est pas un type primitif, mais un objet immuable : il n'existe aucune méthode permettant de modifier sa valeur.

    Jusqu'en java 1.4, on ne pouvait pas faire le moindre calcul avec les objets.

    Depuis java 1.5 et l'arrivée de l'autoBoxing/autoUnboxing, les Objets représentant un type(Integer/Byte/Long...) sont automatiquement convertis en leur type primitif équivalent, mais ce n'est jamais que du sucre syntaxique : v étant immuable, si tu lui affecte une valeur, il est créé un nouvel objet.

    Par exemple dans ton code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    v += 1
    // équivaut en fait a un 
    v = new Integer(v.intValue()++);
    L'objet auquel v faisait référence n'est donc pas modifié.
    en gros il n'est pas possible de garder la valeur modifiée d'une variable en dehors de la fonction.

    j'ai essayé avec un type StringBuffer et la valeur est bel et bien sauvegardée, je conclus donc que le problème vient des types. une idée sur les types qui permettent le référencement des objets ?? j'utiliseré le StrinBuffer au lieu du String, mais qu'en est-il de mon Integer ??
    il n'y a pas de réussite facile, ni d'échec définitif

  4. #4
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 562
    Points : 15 493
    Points
    15 493
    Par défaut
    Les objets Integer,Short, Byte, String, ... sont immuables : leur valeur interne est initialisée dans le constructeur et aucune de leur méthodes ne permet de la modifier.

    StringBuffer est en quelque sorte une version mutable de la classe String. Comme String, elle contient en interne une chaine de caractères, mais ses méthodes permettent de la modifier.

    Il n'y a pas de version mutable des type primitifs numériques en java. Il te faudra les créer toi même.
    par exemple:
    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
    public class c_test{
     
        public c_test() {
        }
     
        public void function1(MutableInteger v){
            v.put( v.get() + 1);
            System.out.println("function1...........   "+v+"  ....................");
        }
     
        public void function2(MutableInteger v){
            v.put( v.get() + 10);
            System.out.println("function2...........   "+v+"  ....................");
        }
     
     
        public static void main(String[] args){
            Testd C = new Testd();
     
            MutableInteger v = new MutableInteger(0);
     
            System.out.println("1 = "+v);
            C.function1(v);
            System.out.println("2 = "+v);
            C.function2(v);
            System.out.println("3 = "+v);
        }
    }
    class MutableInteger{
        private int i;
     
        public int get() {return this.i;}
        public void put(int i) {this.i = i;}
        public MutableInteger(int i) {this.i = i;}
        @Override public String toString() { return new Integer(i).toString();}
     
    }

  5. #5
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par Uther Voir le message
    Il n'y a pas de version muttable des type primitifs numériques en java. Il te faudra les créer toi même.
    En fait, il est possible de détourner les AtomicInteger et consorts pour faire exactement ça : ça marche aussi.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    AtomicInteger i = new AtomicInteger(1);
    System.out.println(i.get());
    i.set(2);
    System.out.println(i.get());
    À aucun moment on n'a créé de nouvel objet AtomicInteger, pourtant la valeur du premier change quand on lui demande.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre régulier Avatar de psycho_xn
    Inscrit en
    Mars 2007
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 250
    Points : 96
    Points
    96
    Par défaut
    Citation Envoyé par thelvin Voir le message
    En fait, il est possible de détourner les AtomicInteger et consorts pour faire exactement ça : ça marche aussi.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    AtomicInteger i = new AtomicInteger(1);
    System.out.println(i.get());
    i.set(2);
    System.out.println(i.get());
    À aucun moment on n'a créé de nouvel objet AtomicInteger, pourtant la valeur du premier change quand on lui demande.
    Merci pour la piste, je vais voir si ça me fera l'affaire avec les Integer.
    je pense que g v utiliser StringBuffer au lieu du String,
    AtomicInteger au lieu du Integer,
    et pour les Short et char ??
    il n'y a pas de réussite facile, ni d'échec définitif

  7. #7
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 562
    Points : 15 493
    Points
    15 493
    Par défaut
    Citation Envoyé par thelvin Voir le message
    En fait, il est possible de détourner les AtomicInteger et consorts pour faire exactement ça : ça marche aussi.
    En effet. Je n'avais pas pensé à utiliser l'AtomicInteger parce que comme tu le dis, c'est un usage détourné. Cette classe est conçue pour résoudre certaines problématiques de concurrence.
    L'utilisation de la classe à cette fin ne devrait cependant pas poser de problème, sauf peut-être des performance légèrement moindre dans certains cas.

    Citation Envoyé par psycho_xn Voir le message
    je pense que g v utiliser StringBuffer au lieu du String,
    AtomicInteger au lieu du Integer,
    et pour les Short et char ??
    Il n'existe pas de AtomicShort ou AtomicChar, mais tu peux évidement les stoquer dans un AtomicInteger.
    Sinon tu peux coder des MutableShort et MutableChar sur le modèle de mon exemple.

  8. #8
    Membre régulier Avatar de psycho_xn
    Inscrit en
    Mars 2007
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 250
    Points : 96
    Points
    96
    Par défaut
    Citation Envoyé par Uther Voir le message
    Sinon tu peux coder des MutableShort et MutableChar sur le modèle de mon exemple.
    si j'adopte la méthode pour coder mes propres types, je serais dans l'obligation de n'utiliser que ces types là. j'ai juste un soucis côté taille de la mémoire occupée par ces types, est-ce qu'il seront toujours codés sur la même taille ??
    il n'y a pas de réussite facile, ni d'échec définitif

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 155
    Points : 199
    Points
    199
    Par défaut
    En ce qui concerne le passage par référence, en général on le fait via un tableau à une dimension.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    /**
     * @param entierInOut tableau d'un entier, modifié.
     */
    void monPlusPlus( int[] entierInOut){
      entierInOut[0]++;
    }
    Perso j'aime pas, ca prête à confusion

    Il y a aussi la possibilité d'utiliser une classe pointeur, je trouve ca déjà plus "propre" (car générique et explicite).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class Pointeur<Type>{
      private Type data;
      Pointeur(){ this.data = null; }
      Pointeur(Type data){ this.data = data; }
      Type get(){ return data; }
      void set(Type data){ this.data = data; }
    }
    Enfin, dans ton cas on peut effectivement utiliser le MutableInteger de Uther dans la mesure où il utilise un type primitif et est donc plus performant (si il y a un gros besoin sur ce niveau là)

    Si il n'y a qu'une valeur à renvoyer, fait une fonction au lieu d'une procédure.

    En général, si l'on a besoin de passer un truc par référence, il se situe déjà dans un autre objet, et c'est donc celui-la que l'on passe en paramètre.

  10. #10
    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
    dans le code donné, la méthode la plus propre, c'est de retourner la nouvelle valeur. Ca marche pas si il y en a plusieurs, mais dans le cas présent c'est la méthode la plus propre:

    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
    public class c_test {
     
        public c_test() {
        }
     
        public Integer function1(Integer v){
            v +=1;
            System.out.println("function1...........   "+v+"  ....................");
            return v;
        }
     
        public Integer function2(Integer v){
            v +=10;
            System.out.println("function2...........   "+v+"  ....................");
            return v;
        }
     
     
        public static void main(String[] args){
            c_test C = new c_test();
     
            Integer v;
            v=0;
     
            System.out.println("1 = "+v);
            v=C.function1(v);
            System.out.println("2 = "+v);
            v=C.function2(v);
            System.out.println("3 = "+v);
        }
    }

  11. #11
    Membre régulier Avatar de psycho_xn
    Inscrit en
    Mars 2007
    Messages
    250
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 250
    Points : 96
    Points
    96
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    dans le code donné, la méthode la plus propre, c'est de retourner la nouvelle valeur. Ca marche pas si il y en a plusieurs, mais dans le cas présent c'est la méthode la plus propre:
    il s'agissait juste d'un simple exemple, mais j'ai des cas où j'ai besoin de faire référence à plusieurs variables
    il n'y a pas de réussite facile, ni d'échec définitif

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    731
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 731
    Points : 574
    Points
    574
    Par défaut
    Citation Envoyé par psycho_xn Voir le message
    il s'agissait juste d'un simple exemple, mais j'ai des cas où j'ai besoin de faire référence à plusieurs variables
    Bonjour, il te suffirait de stocker tes Integer et consorts dans une collection, la passer en paramètre de ta méthode et de modifier les valeurs des différents objets en modifiant donc ta collection avec les nouveaux éléments

Discussions similaires

  1. En Java, c'est bien un passage par référence non ?
    Par _LittleFlea_ dans le forum Général Java
    Réponses: 11
    Dernier message: 17/12/2010, 10h45
  2. Passage par copie vs passage par référence
    Par bolhrak dans le forum C++
    Réponses: 11
    Dernier message: 20/08/2006, 23h37
  3. Réponses: 4
    Dernier message: 26/12/2005, 17h01
  4. Passage par référence
    Par difficiledetrouver1pseudo dans le forum Langage
    Réponses: 9
    Dernier message: 28/09/2005, 11h17
  5. Problème très rapide de passage par référence
    Par Noxexplorer dans le forum ASP
    Réponses: 2
    Dernier message: 23/06/2005, 10h02

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