Effet de bord, aliasing.

Le
Yvon
Bonjour

On crée deux instances du même objet, disons A1 et A2,
avec deux contenus.
Puis on fait A1 = A2.
Si on change ensuite le contenu des champs de A2 on constate que A1 suit le
mouvement et change aussi.
Il semble donc que écrire A1 = A2 signifie A1 et A2 vont faire référence au
même objet et non pas A1 et A2 vont faire référence à 2 objets ayant le
même contenu dans leur champs

C'est vrai aussi pour les paramètres passés aux méthodes. j'avais cru
comprendre qu'ils étaient passés par valeur, mais en pratique ils sont
passés par référence : la variable externe passée en référence est modifiée
si on change sa valeur dans la méthode.

C'est frustrant pour un vieux programmeur du dimanche qui débute en java,
surtout que certaines classes ont un comportement normal ( int,
double,String.), ce qui rend les anomalies difficiles à détecter tant
que l'on n'a pas compris cette finesse.

J'ai résolu le problème pour les classes que je crée, en leur donnant une
méthode :
void copierDans(MemeClasse destination){copier les champs un par un}

Vous, vous faites comment ?
La méthode clone() est elle facile à utiliser ?
--
Yvon.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
jlp
Le #18955461
Yvon a écrit :
Bonjour

On crée deux instances du même objet, disons A1 et A2,
avec deux contenus.
Puis on fait A1 = A2.
Si on change ensuite le contenu des champs de A2 on constate que A1 suit le
mouvement et change aussi.
Il semble donc que écrire A1 = A2 signifie A1 et A2 vont faire référence au
même objet et non pas A1 et A2 vont faire référence à 2 objets ayant le
même contenu dans leur champs

C'est vrai aussi pour les paramètres passés aux méthodes. j'avais cru
comprendre qu'ils étaient passés par valeur, mais en pratique ils sont
passés par référence : la variable externe passée en référence est modifiée
si on change sa valeur dans la méthode.

C'est frustrant pour un vieux programmeur du dimanche qui débute en java,
surtout que certaines classes ont un comportement normal ( int,
double,String....), ce qui rend les anomalies difficiles à détecter tant
que l'on n'a pas compris cette finesse.

J'ai résolu le problème pour les classes que je crée, en leur donnant une
méthode :
void copierDans(MemeClasse destination){copier les champs un par un}

Vous, vous faites comment ?
La méthode clone() est elle facile à utiliser ?


ben tu as réinventé clone() avec un prototype de méthode différent.
En java les types primitifs ( int, long, float, boolean, double ) sont
passés par valeur.
Pour passer des valeurs de ce type par référence il faut utiliser lers
Objets wrapper correspondant ( Integer,Long,Float ...)
String est un cas particulier car immutable ( StringBuffer est mutable ...)
Francois
Le #18955521
Bonjour,

Voici des petites explications qui, je pense, peuvent t'éclaircir un peu
les idées :

En Java, il y a deux types de variables :

1) les variables de type "primitif"
2) les variable de type "référence sur un objet de type A"



1) Pour les variables de type "primitif" (int, byte etc...), le contenu
de la variable se trouve sur une zone mémoire qu'on appelle la pile et
ce contenu c'est ni plus ni moins la valeur (sous forme binaire) de la
variable (la valeur 3 si on a fait "int n = 3;").

Quand tu fais :

int n = 3;
int p = n;

n et p sont deux variables de types "primitif" int. D'un point de vue
mémoire, le contenu de n et celui de p se trouvent sur deux zones
mémoires distinctes (toutes les deux sur la pile). Ces deux zones
contiennent toutes les deux la valeur 3 (en écriture binaire). Bref,
c'est comme du langage C dans le cas 1).



2) Pour les variable de type "référence sur un objet de type A", on va
prendre un exemple :

Animal a = new Animal();

La variable a est une variable de type "référence sur des objet de type
Animal". On dit aussi (pour aller plus vite) que la variable a est de
"type statique Animal".

Le contenu de la variable a est également sur la pile mais son contenu
n'est pas l'objet Animal. Son contenu sur la pile est une "référence sur
les objets de type Animal". D'un point de vue imagé, on pourrait dire
que la variable a contient une "télécommande pour contrôler des objets
de type Animal", si bien que faire "a.getNom();" revient à appuyer sur
le bouton "donne moi ton nom" de la télécommande.

Et l'objet Animal, où est-il alors ? Il est sur une autre zone mémoire
que la pile qui s'appelle le tas. La télécommande sur la pile contrôle
l'objet de type animal qui se trouve sur le tas. On pourrait dire que la
variable de type "référence sur des objets de type Animal" «pointe» vers
l'objet Animal se trouvant sur le tas. Sauf que le mot «pointe» on
l'utilise pas trop en Java car ça fait penser aux pointeurs du langage C
qui n'existent pas en Java.

Quand tu fais :

Animal a1 = new Animal();
Animal a2 = a1;

Après la première ligne, le contenu de a1 sur la pile est une "référence
sur des objets de type Animal" qui fait référence (qui «pointe») vers un
objet de type Animal se trouvant sur le tas (zone mémoire disjointe de
la pile). Autrement dit, le contenu de a1 sur la pile est une
télécommande qui contrôle un objet de type Animal sur le tas.
Après la deuxième ligne, le contenu de la variable a1 est bien copié
dans la zone mémoire de a2 (on est sur la pile). Donc a2 contient la
même "référence sur des objets de type Animal" que a1, autrement dit a1
et a2 contiennent la même télécommande qui contrôle le même objet
Animal. Sur le tas, l'objet Animal est unique (il n'a pas été dupliqué),
mais il y a deux télécommandes qui "pointe" vers lui.

Voilà.

La copie des arguments d'une méthode sur ses paramètres se fait bien par
valeurs. Mais cette expression est traite car dans le cas d'une variable
de type "référence sur un objet de type Animal", la valeur copiée c'est
la référence elle-même et non l'objet avec toutes les conséquences que
cela entraîne.


J'ai résolu le problème pour les classes que je crée, en leur donnant une
méthode :
void copierDans(MemeClasse destination){copier les champs un par un}

Vous, vous faites comment ?
La méthode clone() est elle facile à utiliser ?



La notion d'égalité d'objets, de clonage d'objets est une chose assez
compliquée (pour moi en tout cas) et là je laisse les autres te répondre.

J'espère avoir été clair et n'avoir pas dit trop de bêtises (n'hésitez
pas à me rectifier).


--
François Lafont
Publicité
Poster une réponse
Anonyme