Bonjour,
j'aimerai savoir comment faire pour cloner une classe mais en dupliquant également la valeur des attributs, ce que ne fait pas la méthode "clone()".
Merci
Bonjour,
j'aimerai savoir comment faire pour cloner une classe mais en dupliquant également la valeur des attributs, ce que ne fait pas la méthode "clone()".
Merci
On "clone" des objets et non des classes...
Tu dois pour cela redéfinir la méthode clone pour qu'elle fasse ce que tu veux.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 public MonObjet clone(MonObjet B){ MonObjet A=new MonObjet(); A.setAttribut1(B.getAttribut1); //le reste du traitement return A; }
Envoyé par afrikha
FAUX !
Dans ton exemple, l'attribut B n'est pas dupliqué. L'attribut A et l'attribut B référencent la même valeur.
Moi je voudrais cloner les attributs également
Ce que tu peut faire, c'est prendre chaque attribut de la classe à cloner et les cloner et ensuite mettre le clone de ces attributs dans le clone de la classe.
Oui en gros je voulais savoir si il existait une méthode proche de la méthode clone() mais qui faisiat un clone total, c'est à dire qui duplique l'objet, ses attributs et la valeur des attributs.
Si cela n'existe pas, j'opterai alors pour une autre facon de faire, en l'occurence redéfinir la méthode clone et cloner mes attributs un par un.
Ah la la, je suis mal réveillé moi, mais bon ce n'est pas une raison
Je ne vois pas d'autres solutions à part celle proposé par wichtounet.
Le problème c'est que mon objet comporte des attributs de types différents : String ,int et des types Objet.Envoyé par wichtounet
Or , la classe String par exemple, n'implémente pas l'interface Cloneable, ce qui signifie que pour cloner une valeur de type String, je suis obligé de faire dériver la classe String en une classe String1 qui va implémenter la classe Cloneable et tous mes attributs de type String devront être de type String1 : extrémement lourd...
Question stupide : Pourquoi ne pas appeler le constructeur dans la méthode clone ?
Je ne vois pas du tout l'intérêt, explique toi. (je rappele que je suis capable de cloner un objet mais pas la valeur de ses attributs)
C'était effectivement une question stupide, tu es quand même obligé de cloner tes attributs un à un.
Je regrette de ne pas pouvoir t'aider d'avantage
Salut,
Et surtout impossible : on ne peut pas étendre la classe String...Envoyé par danyboy85
A la rigueur tu pourrais surement passer par la Reflection pour "cloner" tous les attributs qui implémente Cloneable (et encore il me semble que ce n'est pas une condition suffisante pour que ce soit possible).
Mais bien sûr cela ne marchera pas avec les objets non-cloneable...
Question : Pourquoi as-tu besoin de cloner tous les attributs de l'objet ???
a++
Bon les pros du java je vous est posé une colle on dirait pourtant je crois avoir trouvé la solution : l'introspection.
En effet la classe Fields implément l'interface Cloneable :
Edit : bien joué AdiGuba tu avais trouvé avant moi
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 public Object clone() throws CloneNotSupportedException { MonObjet objectCopie = (MonObjet)super.clone(); //dupliquer le contenu des attributs Field[] attributsClone = (Field[])this.getClass().getDeclaredFields().clone(); Field[] attributsObjectCopie = objectCopie.getClass().getDeclaredFields(); for (int i=0; i<attributsClone.length; i++) { attributsObjectCopie[i] = attributsClone[i]; } return objectCopie; }
Pour ce qui est de String, je pense pas que c'est un gros problème...Envoyé par danyboy85
Du fait de son immuabilité, tu t'en fous un peu de prendre la même référence et en plus, c'est pas très dur d'en faire un clone.
Sauf que ton code est fauxEnvoyé par danyboy85
Donc tu n'a pas cloner les attributs...
- La classe Field n'est pas Cloneable, et de toute manière elle représente une vue sur un attribut mais en aucun cas sa valeur.
- Tu ne clone pas des Fields mais un tableau de Field. Or lorsqu'on clone un tableau on ne clone que le conteneur et non pas le contenu (les objets des deux tableaux sont identiques).
Il faudrait que tu parcours le tableau de Field et que tu appelles la méthode get() pour récupérer la valeur de chaque attribut.
Ensuite si ce dernier est Cloneable, il faut essayer d'appeller la méthode clone() via reflection (puisqu'elle est déclaré protected par défaut tu ne pourra pas l'appeller directement).
Enfin si le cloneage à réussi il te faudra modifier la valeur de l'attribut avec la méthode set()...
Tout cela en gérant un grand nombre d'exception...
a++
En effet... tu as entièrement raison.
Bon si quelqu'un a une méthode plus simple je suis preneur.
Car j'ai besoin de 2 objets distincts, qui n'ont aucune référence commune.Envoyé par adiGuba
En fait je crée un sorte d'éditeur HTML et lorsque l'utilisateur copie un bouton par exemple, le bouton copié doit avoir les mêmes propriétés que le bouton d'origine mais la modification d'une propiété de l'un ne doit en aucun cas modifier la valeur de la propriété de l'autre.
Hello,
Deux problèmes se posent à mon avis:
- est ce que en passant par l'introspection et sachant que tu vas récupérer un Object, est ce que le Object.clone() va te donner la méthode clone() de Oject ou de ta sous-classe (là je pense que la seconde proposition est vraie).
- et si jamais ton attribut est un autre objet avec des autres attributs, que vas-tu-faire ?
Donc pour avoir deux objects distincts c'est pas évident. Le deep clone c'est pas facile
A+
C'est quoi l'immuabilité ?Envoyé par wichtounet
Ah bon et pourquoi ?Envoyé par wichtounet
Et comment ?Envoyé par wichtounet
Salut,
Pour les types primitifs, aucun souci de clonage.
Pour ce qui est des objets, pourquoi ne pas utiliser les constructeurs par copie ? Si ce sont des bons constructeurs, ils ne copient pas la référence mais bien l'objet en lui même. Exemple de la classe String :
Exactement ce que tu veux. Apres si ce sont tes propres objets, bah développes des constructeurs par copie qui invoquent en cascade des constructeurs par copie, etc etcInitializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string.
Je ferais ça moi
Bon courage
Fred
edit : immuabilité veut dire que tu ne peux changer l'objet. Si tu fais par exemple :
c'est équivalent à :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 String s="coucou"; s=s+" c'est moi";
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 String s="coucou"; s=new String("coucou c'est moi");
- Oui c'est pas bête et ca POURRAIT résoudre mon problème cette idée de constructeur mais dans le cadre de mon appli c'est impossible à gérer (objets héritées, Factory...). En gros je ne connais pas toujours le type de l'objet que je dois clonerEnvoyé par mavina
- J'ai trouvé une autre méthode : la sérialisation. Bon je vais me faire lyncher par certains mais en tout cas ca fonctionne :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 public Object copi() throws IOException, ClassNotFoundException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(this); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); Object deepCopy = ois.readObject(); return deepCopy; }
Pour ton code sur la sérialisation, il manque des bloc try/finally afin de fermer correctement les flux.
Jette un coup d'oeil sur le tutoriel : java.io
Partager