Toutes les approches pour copier des objets en Java ont de sérieux problèmes:
Clone
- La méthode clone() est protégé, de sorte que vous ne pouvez pas l'appeler directement, à moins que la classe en question la remplace avec une méthode publique.
- clone() n'appelle pas le constructeur. De tout constructeur. Il va allouer de la mémoire, d'attribuer à l'interne
class
domaine (que vous pouvez lire via getClass()
) et de copier les domaines de l'original.
Pour des problèmes plus avec le clone(), voir le point 11 de Joshua Bloch du livre "Effective Java, Deuxième Édition"
Sérialiser
Sérialiser est encore pire; il a beaucoup de défauts, clone()
et puis certains. Josué a un chapitre entier avec quatre points pour ce seul sujet.
Ma Solution
Ma solution est d'ajouter une nouvelle interface pour mes projets:
public interface Copyable<T> {
T copy ();
T createForCopy ();
void copyTo (T dest);
}
Le code ressemble à ceci:
class Demo implements Copyable<Demo> {
public Demo copy () {
Demo copy = createForCopy ();
copyTo (copy);
return copy;
}
public void createForCopy () {
return new Demo ();
}
public void copyTo (Demo dest)
super.copyTo (dest);
...copy fields of Demo here...
}
}
Malheureusement, j'ai copier ce code à tous mes objets, mais c'est toujours le même code, si je peux utiliser une Éclipse de l'éditeur de modèle. Avantages:
- Je peux décider quel constructeur à appeler et comment initialiser le champ.
- L'initialisation se passe dans un déterministe de l'ordre (de la racine de la classe à la classe d'instance)
- Je peux réutiliser les objets existants et les remplacer
- Type de coffre-fort
- Les Singletons séjour singletons
Pour les types standards Java (comme les collections, etc), j'utilise une classe utilitaire qui peut copier ceux-ci. Les méthodes ont des drapeaux et des rappels, afin que je puisse contrôler la profondeur de la copie devrait être.