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 :

Copie profonde sur classe paramétrée


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Août 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2010
    Messages : 8
    Par défaut Copie profonde sur classe paramétrée
    Hello!

    Je bute sur un petit problème, j'ai ici une classe avec un type paramétré qui implémente la méthode clone()

    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
    21
    22
     
    public class MaClasse<T>
    {
     
        private T param;
     
        public MaClasse(T param)
        {
            this.param = param;
        }
     
        public MaClasse(MaClasse uneAutreMaClasse)
        {
            this.param = (T) uneAutreMaClasse.param.clone();
        }
     
        @Override
        public MaClasse clone()
        {
            return new HpsToolPosition(this);
        }
    }
    Problème : clone() est une méthode protected, comme j'utilise un type paramétré, le package de T est donc java.lang, puisqu'il est considéré comme un Object.

    Si je ne clone pas param, ça fonctionne, mais ça n'assure pas la copie profonde que l'on voudrait avec la méthode clone().

    Est-ce qu'un de vous entreverrait une solution à ceci?

    Merci d'avance!

  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,


    Quelques remarques :
    • Le constructeur MaClasse(MaClasse) devrait utiliser un type paramétré lui aussi, soit : MaClasse(MaClasse<T>).
      A noter toutefois qu'en Java il est plutôt inhabituel d'utiliser un constructeur de copie comme ceci...
    • Tu ne respectes pas les règles du cloneage en Java. Il ne faut pas créer un nouvel objet, mais implémenter l'interface Cloneable et retourner l'objet retourné par super.clone()
    • Tu peux obliger le type T a être cloneable en le définissant comme ceci : <T extends Cloneable>.
      Malheureusement l'interface Cloneable ne définit pas de méthode clone(), donc tu dois passer par l'API de reflection pour l'appeler sur n'importe quel type implémentant Cloneable.



    Bref cela donnerait quelque chose comme ceci :
    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    public class MaClasse<T extends Cloneable> implements Cloneable {
     
        private T param;
     
        public MaClasse(T param) {
            this.param = param;
        }
     
        public MaClasse(MaClasse<T> uneAutreMaClasse) {
            this.param = uneAutreMaClasse.cloneParam();
        }
     
        /** Méthode interne qui permet de cloner le paramètre par reflection */
        private T cloneParam() {
            try {
                Method cloneMethod = Object.class.getMethod("clone");
                cloneMethod.setAccessible(true);
                @SuppressWarnings("unchecked")
                T clonedParam = (T) cloneMethod.invoke(this.param);
                return clonedParam;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
     
        @Override
        public MaClasse<T> clone() {
            try {
                @SuppressWarnings("unchecked")
                MaClasse<T> cloned = (MaClasse<T>) super.clone();
                cloned.param = cloned.cloneParam();
                return cloned;
            } catch (CloneNotSupportedException e) {
                // Ceci ne devrait jamais arriver tant qu'on implémente bien Cloneable
                throw new RuntimeException(e);
            }
        }
    }

    a++

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Août 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2010
    Messages : 8
    Par défaut
    Je crois que tu viens de révolutionner ma façon de voir Java
    La réflexion, c'est une sorte d'introspection?

    Citation Envoyé par adiGuba Voir le message
    A noter toutefois qu'en Java il est plutôt inhabituel d'utiliser un constructeur de copie comme ceci...
    C'est plus une habitude, c'est comme ça que mon prof de java m'avait montrer le clone, en utilisant un constructeur de copie, et ça m'est resté

    Citation Envoyé par adiGuba Voir le message
    Tu ne respectes pas les règles du cloneage en Java. Il ne faut pas créer un nouvel objet, mais implémenter l'interface Cloneable et retourner l'objet retourné par super.clone()
    Par là, tu veux dire que pour faire bien, il faut laisser java cloner l'objet, et reprendre à la main ce qu'on a implémenté perso?


    J'imagine que dans le clone(), lorsque tu as mis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cloned.param = cloned.cloneParam();
    c'est plutôt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cloned.param = this.cloneParam();
    ?


    En tout cas, grand merci, ça rox ton code!

  4. #4
    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
    Citation Envoyé par lepak Voir le message
    La réflexion, c'est une sorte d'introspection?
    Oui !



    Citation Envoyé par lepak Voir le message
    C'est plus une habitude, c'est comme ça que mon prof de java m'avait montrer le clone, en utilisant un constructeur de copie, et ça m'est resté
    C'est très utilisé en C++ car c'est implicite lors d'une affectation/passage de paramètre, mais c'est assez rare en Java...



    Citation Envoyé par lepak Voir le message
    Par là, tu veux dire que pour faire bien, il faut laisser java cloner l'objet, et reprendre à la main ce qu'on a implémenté perso?
    Oui par convention c'est ce qu'il faudrait faire (cf la javadoc de clone()).

    Cela permet également d'être sûr que clone() renverra le bon type dans les éventuelles classes filles sans qu'on ait forcément besoin de redéfinir la méthode



    Citation Envoyé par lepak Voir le message
    J'imagine que dans le clone(), lorsque tu as mis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cloned.param = cloned.cloneParam();
    c'est plutôt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cloned.param = this.cloneParam();
    ?
    En fait c'est la même chose car à ce moment précis cloned.param et this.param référencent le même objet en mémoire


    a++

Discussions similaires

  1. syntaxe css lien sur classe
    Par mussara dans le forum Mise en page CSS
    Réponses: 8
    Dernier message: 03/08/2005, 09h52
  2. [K&R] Copie entrée sur sortie
    Par sorry60 dans le forum C
    Réponses: 7
    Dernier message: 25/04/2005, 21h32
  3. [C#] Evenement sur classe virtual
    Par papouAlain dans le forum Windows Forms
    Réponses: 26
    Dernier message: 11/01/2005, 11h45
  4. [VB.NET] Instanciation objet (sur class perso.)
    Par DaxTaz dans le forum ASP.NET
    Réponses: 4
    Dernier message: 03/05/2004, 11h07
  5. est il possible de faire un trie sur un paramètre donné
    Par chtiboss dans le forum XSL/XSLT/XPATH
    Réponses: 8
    Dernier message: 17/03/2004, 11h51

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