HOWTO · Java
Tableau passé par valeur ou passé par référence en Java
Cet article présente la vérification si le tableau est passé par valeur ou passé par référence en Java.
Sur cette page
Java transmet chaque argument de méthode par valeur. Lorsque l’argument est un tableau, la valeur copiée dans le paramètre est une référence vers l’objet tableau. La variable de l’appelant et le paramètre peuvent donc désigner le même objet, tout en restant deux variables distinctes. Cela explique pourquoi la modification d’un élément est visible par l’appelant, alors que l’affectation d’un autre tableau au paramètre ne l’est pas.
Comment Java transmet ses arguments
Une référence est une valeur qui permet au code d’accéder à un objet ; ce n’est pas l’objet lui-même. Une méthode reçoit une copie de cette valeur de référence. Au début de l’appel, la variable tableau de l’appelant et le paramètre de la méthode désignent le même objet tableau. Java ne transmet pas la variable tableau elle-même par référence : la méthode ne peut donc pas remplacer la variable de l’appelant en affectant une autre valeur à son propre paramètre.
Il faut distinguer la modification d’un objet de celle d’une variable. L’affectation d’une valeur à un élément du tableau modifie l’objet partagé. L’affectation d’une valeur au paramètre ne modifie que la référence copiée de ce paramètre. Ces deux opérations ont des effets différents, même si elles ont lieu toutes deux dans la méthode appelée.
Comment la modification d’un élément du tableau affecte l’appelant
Lorsqu’une méthode écrit dans values[index], elle modifie un élément de l’objet tableau auquel les deux références donnent accès. Après le retour de la méthode, l’appelant voit cet élément modifié. La référence a été transmise par valeur ; la modification reste visible parce que la référence copiée désigne toujours le même objet.
Que se passe-t-il lorsqu’une méthode réaffecte un paramètre tableau ?
Affecter un nouveau tableau au paramètre fait désigner à celui-ci un autre objet. Cela ne modifie pas la variable de l’appelant, qui désigne toujours le tableau d’origine. L’appelant voit les modifications apportées à l’objet d’origine avant la réaffectation, mais ne reçoit pas la nouvelle référence du paramètre. Pour remplacer le tableau de l’appelant, renvoyez le nouveau tableau et affectez la valeur de retour à l’endroit de l’appel, ou modifiez le tableau d’origine.
Comportement des paramètres primitifs
Les arguments primitifs sont eux aussi transmis par valeur : le paramètre reçoit une copie de la valeur primitive. Si une méthode affecte un autre nombre à ce paramètre, la variable de l’appelant reste inchangée. C’est comparable à la réaffectation d’un paramètre tableau, et non à la modification d’un élément du tableau. Dans le cas d’un tableau, la valeur copiée est une référence : elle permet de modifier l’objet partagé, tandis que l’affectation d’une nouvelle référence ne concerne que le paramètre local.
Exécutez cet exemple autonome :
Le code et les libellés ou sorties affichés dans cette section restent en anglais.
public class ArrayArgumentDemo {
static void changeFirst(int[] values) {
values[0] = 9;
}
static void replaceParameter(int[] values) {
values = new int[] {7, 8};
}
static void changeNumber(int number) {
number = 9;
}
public static void main(String[] args) {
int[] numbers = {1, 2};
changeFirst(numbers);
System.out.println(numbers[0]);
replaceParameter(numbers);
System.out.println(numbers[0]);
int count = 1;
changeNumber(count);
System.out.println(count);
}
}
9
9
1
Le premier affichage montre l’élément modifié. Le deuxième montre que le tableau de l’appelant reste inchangé après l’affectation d’un autre tableau au paramètre de la méthode. Le dernier montre que la variable primitive de l’appelant reste elle aussi inchangée. L’exemple affiche 9, 9 et 1, dans cet ordre.
À retenir
Java transmet toujours ses arguments par valeur, y compris les références vers des tableaux. La modification d’un élément est visible lorsque la variable de l’appelant et le paramètre de la méthode désignent le même objet tableau. La réaffectation du paramètre ne modifie que sa référence locale, et l’affectation d’une nouvelle valeur à un paramètre primitif ne modifie que sa copie locale. En distinguant la modification d’un objet de la réaffectation d’un paramètre, on peut prévoir le comportement du code.