En Java, les paramètres sont passés en référence ou en valeur?

J’ai toujours pensé que Java utilisait le passage en référence.

Cependant, j’ai vu un article quleque part qui affirme que Java utilise le passage en valeur.

Je ne comprends pas la distinction qu’ils font.

Quelle est l’explication ?

Java fait passer les références par valeur.

Vous ne pouvez donc pas modifier la référence qui est transmise.

En fait, la réaffectation des paramètres de l’objet n’affecte pas l’argument, par exemple,

private static void myfunction(Object var) {
    var = null;
}

public static void main(String[] args) {
    String str = "Hello";
    myfunction(str);
    System.out.println(str);
}

Cela va afficher « Hello » au lieu de null.

La raison pour laquelle cela fonctionne est que ‹ var › est une copie de la valeur de ‹ str ›, qui est juste une référence à « Hello ». S’il s’agissait de la référence elle-même, alors myfunction aurait redéfini ‹ str › à null.

Avant l’appel à myfunction():

2

Aprés l’appel à myfunction():

1

Java n’a que le passage par valeur. Un exemple très simple pour valider cela.

public void test() {
    MaClass obj = null;
    init(obj);
    //Après avoir appelé la méthode init, obj pointe toujours vers null
    //C'est parce que obj est passé comme valeur et non comme référence.
}
private void init(MaClass myObj) {
    myObj = new MaClass();
}
1 « J'aime »

L’une des plus grandes confusions dans le langage de programmation Java est de savoir si Java utilise le passage par référence ou passage par valeur.

Tout d’abord, nous devons comprendre ce qu’on entend par passage par valeur ou passage par référence.

  • Passage par valeur : Les valeurs des paramètres de la méthode sont copiées dans une autre variable, puis l’objet copié est transmis, c’est pourquoi on l’appelle passage par valeur.

  • Passage par référence : Un alias ou une référence au paramètre réel est transmis à la méthode, c’est pourquoi on l’appelle passage par référence.

2 « J'aime »

je ne suis pas tout a fait d accord avec l explication fournie, car un exemple peut cacher une subtilité.
Quand on transfert un objet, c est bien la référence qui est pasée et de fait la fonctoin « myfonction » pourrait modifier la valeur pointée.
Sauf que … String est un type immutable, c est a dire que toute action sur String provoque une copie de sa valeur, ce qui explique que dans l exemple fourni, la valeur en sortie n a pas évoluée !
Refait l exemple avec un objet autre, et la valeur changera :slight_smile:
c est ce qui me posait problème avec le shéma tel que présenté : lorsqu on lit le shéma fourni, on voir bien que var peut parfaitement changer la valeur de l’attribut… sauf pour un string ou un type de base java :slight_smile:

Java transmet toujours les arguments par valeur, et NON par référence. Je suis d’accord avec vous, la référence est modifié à l’intérieur de la fonction mais pas à l’extérieur.

Oui, je suis d’accord avec vous et ça dépend. Prenons l’exemple suivant:

public class Main 
{
    public static void main(String[] args) 
    {
        Person p = new Person("Alex");
        updateReference(p); // Cela ne changera pas la référence
        System.out.println(p.getName());   // Alex
        modifyReference(p); // Il modifiera l'objet auquel la variable de référence "p" fait référence !
        System.out.println(p.getName());   // Ali
    }

    public static void updateReference(Person a) {
        Person b = new Person("Bob");
        a = b;
    }

    public static void modifyReference(Person x) {
        x.setName("Ali");
    }
}

class Person 
{
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}

Je vais vous expliquer cela par étapes :

Etape 1 : Nous avons déclaré une référence nommée ‹ p › de type ‹ Person › et lui attribuer un nouvel objet de type ‹ Person › avec la valeur « alex ».

Person p = new Person("alex");

en-java-les-parametres-sont-passes-en-reference-ou-en-valeur-1

Etape 2 : En ce qui concerne la méthode ‹ updateReference() ›, une référence de type ‹ Person › avec un nom ‹ a › est déclarée et on lui attribue initialement ‹ null › par défaut.

public static void updateReference(Person a)

en-java-les-parametres-sont-passes-en-reference-ou-en-valeur-2

Etape 3 : Lorsque vous appelez la méthode ‹ updateReference() ›, la référence ‹ a › sera assignée à l’objet qui est passé comme argument ‹ p ›.

updateReference(p);

en-java-les-parametres-sont-passes-en-reference-ou-en-valeur-3

Etape 4 : Ensuite, nous avons déclarer une référence nommée ‹ b › de type ‹ Person › et lui attribuer un nouvel objet de type ‹ Person › avec la valeur « bob ».

Person b = new Person("Bob");

en-java-les-parametres-sont-passes-en-reference-ou-en-valeur-4

Etape 5 : Ensuite, on fait une nouvelle affectation à la référence ‹ a › (et non ‹ p ›) de l’objet dont la valeur est « Bob ».

a = b;

en-java-les-parametres-sont-passes-en-reference-ou-en-valeur-5

Etape 6 : Lorsque vous appelez la méthode ‹ modifyReference() ›, une référence ‹ x › est créée et on lui attribue l’objet ‹ p › avec l’attribut « Alex ».

public static void modifyReference(Person x)

en-java-les-parametres-sont-passes-en-reference-ou-en-valeur-6

Etape 7 : La ligne suivante changera l’attribut de l’objet que la référence ‹ x › pointe vers lui, et c’est le même objet que la référence ‹ p › pointe vers lui.

x.setName("Ali");

en-java-les-parametres-sont-passes-en-reference-ou-en-valeur-7

j’espère que j’étais clair :slight_smile:

Java passe toujours les arguments par valeur, mais ce que vous passez par valeur est une référence à un objet, pas une copie de l’objet.