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

Langage Java Discussion :

[Language][Clone] Bizarrerie


Sujet :

Langage Java

  1. #1
    Membre Expert
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Par défaut [Language][Clone] Bizarrerie
    Bonjour,

    Je travaillais sur des Vecteurs contenant des tableaux et j'avais besoin de changer juste quelques valeurs d'un des tableaux, valeurs qui pouvaient s'averer "néfastes".
    J'ai donc fait un clone du vecteur de base pour avoir une copie de sauvegarde au cas où il y'aurait des erreurs dans l'autre et je suis tombé sur une constatation étrange :

    lorsqu'on clone un objet (un vecteur en tout cas), le clone se contente de faire une copie de "premier degré" des objets qu'il contient puis des références pour les sous-objets.

    En effet, voilà ce qui m'est arrivé :

    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
    Vector v = new Vector() // normal...
    v.add(new String[]{"A","B","C"});
     
    // Clonage de v
    backUpV = (Vector)v.clone();
     
    // Changement de "A" en "D" dans le vecteur v
    ( (String[])v.elementAt(0) )[0] = "D";
     
    /* ou bien (c'est equivalent dans les faits) :
     * String[] contenuV = ((String[])v.elementAt(0));
     * contenuV[0] = "D";
     * v.setElementAt(contenuV,0);
     */
     
    // Affichage du resultat
    System.out.println(
         "premiere lettre de v = "+( (String[])v.get(0) )[0]+"\n"+
         "premiere lettre de backUpV = "+( (String[])backUpV.get(0) )[0]
    );
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Le résultat attendu est :
    premiere lettre de v = D
    premiere lettre de backUpV = A
     
    Mais contre toute attente il s'affiche :
    premiere lettre de v = D
    premiere lettre de backUpV = D
    Une alternative qui fonctionne est d'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    String[] contenu = new String[v.size()];
    // Transfert du contenu de v dans 'contenu'
    for (int i=0; i<contenu.length; i++)
       contenu[i] = ((String[])v.elementAt(0))[i];
     
    contenu[0] = "D";
    v.setElementAt(contenu,0);
    Est-ce un "bug" dans la méhode clone() ou bien est-ce désiré ?

    Dans tout les cas c'est étrange (et ennuyeux aussi...)

    Loceka.

  2. #2
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    C'est normal puisque les Vecteurs ne contiennent qu'une référence vers l'objet qu'ils contiennent.

    Donc les deux vecteurs contiennent le même objet (le tableau). Lorsque tu le modifies il est modifié dans les deux vecteurs...

    Dans le second cas tu crée un nouveau tableau donc tu as deux objets et lorsque tu en modifies un tu ne modifies pas l'autre...

    a++

  3. #3
    Membre Expert
    Avatar de zekey
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 036
    Par défaut
    Ben dans la doc de l'API c'est dit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Returns a clone of this vector. The copy will contain a reference to a clone of the internal data array, not a reference to the original internal data array of this Vector object.
    C'est pas marqué qu'il duplique les objets contenus.
    Pourquoi irait-il cloné recursivement tous les objets et les sous objets et les sous-sous objets..... et mettre toutes les références a jour. Imagine le bordel

  4. #4
    Membre Expert
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Par défaut
    Citation Envoyé par ze_key
    Pourquoi irait-il cloné recursivement tous les objets et les sous objets et les sous-sous objets..... et mettre toutes les références a jour.
    Pour faire un vrai clone, totalement indépendant de la source par exemple.

    Je croyais que c'était le comportement par défaut de la méthode clone (un peu comme la serialization, qui sérialize tous les objets en appelant leur méthode de sérialization).

    Mais si c'est pas un bug alors tant mieux.

  5. #5
    Membre Expert

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 301
    Par défaut
    Citation Envoyé par Loceka
    Je croyais que c'était le comportement par défaut de la méthode clone
    justement pas. d'ailleurs, dans la javadoc de "Object", on peut lire ceci:
    Creates and returns a copy of this object. The precise meaning of "copy" may depend on the class of the object. The general intent is that, for any object x, the expression:

    x.clone() != x

    will be true, and that the expression:

    x.clone().getClass() == x.getClass()

    will be true, but these are not absolute requirements. While it is typically the case that:

    x.clone().equals(x)

    will be true, this is not an absolute requirement.
    en gros, chaque classe peut implémenter la méthode clone de la manière qu'elle le souhaite... il faut gérer au cas par cas


  6. #6
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    J'en parle un peu ici : http://www.progx.org/index.php?section=articles&article=Design%20Patterns/article4

    Tu peux parfois contourner le probleme en faisant le clonage a l'aide de la serialisation.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. quel est le Meilleur language pour piloter le port serie ?
    Par flyfab dans le forum Langages de programmation
    Réponses: 7
    Dernier message: 21/07/2003, 10h03
  2. [postgresql] Probleme de language SQL
    Par sbucci dans le forum Requêtes
    Réponses: 3
    Dernier message: 31/05/2003, 13h19
  3. Language
    Par bidson dans le forum XMLRAD
    Réponses: 4
    Dernier message: 10/05/2003, 19h28
  4. [Appli][Autre language]dll-contenant form
    Par flash dans le forum Langage
    Réponses: 6
    Dernier message: 20/09/2002, 14h18
  5. je veux apprendre la programmation quel language choisir??
    Par existance dans le forum Débuter
    Réponses: 26
    Dernier message: 06/08/2002, 05h32

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