ProgrammationDéveloppeur Backend

Comment fonctionne le mécanisme de passage des paramètres dans les méthodes Java (pass-by-value), et en quoi cela peut-il différer des autres langages de programmation ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

En Java, il y a toujours un mécanisme pass-by-value (passage par valeur), mais il y a une particularité pour les objets :

  • Pour les types primitifs, la valeur elle-même est copiée.
  • Pour les objets, c'est la valeur de la référence à l'objet qui est copiée, mais pas l'objet lui-même.

Ainsi, la modification des champs de l'objet à l'intérieur de la méthode se reflète sur l'objet original, tandis que la tentative d'assigner une nouvelle référence à une variable à l'intérieur de la méthode n'affecte pas l'objet original. Cela est souvent confondu avec le pass-by-reference, mais Java ne supporte pas le pass-by-reference !

Exemple :

void changePrimitive(int a) { a = 10; } void changeObject(Point p) { p.x = 10; } int num = 5; changePrimitive(num); // num est toujours 5 Point pt = new Point(1, 2); changeObject(pt); // maintenant pt.x == 10

Important ! Si à l'intérieur de la méthode on assigne p = new Point(100, 200), l'objet d'origine en dehors de la méthode ne changera pas. On modifie un champ de l'objet, pas sa référence !

Question piège

Question : Peut-on changer un objet passé en argument, de sorte qu'en dehors de la méthode, la variable-référence pointe vers un nouvel objet ?

Réponse : Non, on ne peut pas. Lors de l'assignation d'une nouvelle référence à l'argument à l'intérieur de la méthode, cela ne concerne que la copie de la référence, qui disparaît après la sortie de la méthode. En dehors de la méthode, la variable-argument pointe toujours vers l'ancien objet.

void reassign(Point p) { p = new Point(100, 200); // uniquement localement ! } Point pt = new Point(5, 5); reassign(pt); // pt est toujours (5, 5)

Exemples d'erreurs réelles dues à l'incompréhension des subtilités du sujet


Histoire

Dans un grand système financier, un API a été implémenté, qui "retournait" des modifications à un objet en modifiant la référence à l'intérieur de la méthode. En conséquence, après la sortie de la méthode, les modifications n'étaient pas reflétées. Il a fallu redessiner complètement une partie de la logique pour clairement distinguer la mutation et le retour de nouveaux objets.


Histoire

Lors de la tentative de réaliser un échange pour deux objets en Java avec la méthode swap(A a, B b), le développeur passait des références et les échangeait à l'intérieur de la méthode. Cela n'a pas fonctionné. Il fallait soit retourner le résultat, soit utiliser des conteneurs-tableaux. L'ignorance du pass-by-value a conduit à un échange incorrect d'objets.


Histoire

Un des participants au projet a migré la logique depuis C++ et s'attendait à un comportement de pass-by-reference. En conséquence, les méthodes ont cessé de fonctionner correctement : les modifications à l'intérieur de la méthode ne "sortaient" pas. Il a fallu réécrire en urgence des parties critiques du code, ce qui a pris beaucoup de temps.