110 votes

À propos de Java clonable

Je cherchais des tutos expliquant à propos de Java Cloneable, mais n'a pas obtenu de bons liens, et de Débordement de Pile est de plus en plus évident le choix de toute façon.

Je voudrais savoir les suivantes:

  • un.) Cloneable signifie que nous pouvons avoir un clone ou une copie d'objets, par la mise en œuvre de l' Cloneable interface. Quels sont les avantages et les inconvénients de le faire?
  • b.) Comment le récursive clonage se produire si l'objet est un objet composite?

Je vous remercie.

172voto

Bozho Points 273663

La première chose que vous devez savoir à propos de Cloneable est - ne l'utilisez pas.

Il est très difficile de mettre en œuvre le clonage avec Cloneable droit, et l'effort en vaut pas la peine.

Plutôt que d'utiliser les autres options, comme apache commons SerializationUtils (deep-clone) ou BeanUtils (shallow-clone), ou tout simplement utiliser un constructeur par copie.

Voir ici pour le point de vue de Josh Bloch à propos du clonage, avec Cloneable, ce qui explique les nombreux inconvénients de l'approche.

43voto

Luke Hutteman Points 1153

Clonable lui-même n'est malheureusement qu'un marqueur de l'interface, c'est: il ne définit pas la méthode clone ().

Ce qui est fait, est de modifier le comportement de l'Objet protégé.méthode clone (), qui va lancer une CloneNotSupportedException pour les classes qui n'implémentent pas Clonable, et d'effectuer un membre de la sage-copie pour les classes qui ne.

Même si c'est le comportement que vous cherchez, vous aurez toujours besoin pour mettre en œuvre votre propre méthode clone() afin de la rendre publique.

Lors de la mise en œuvre de votre propre clone(), l'idée est de commencer avec l'objet créer par super.clone(), qui est garanti pour être de la classe correcte, puis effectuez l'une population supplémentaire de champs dans le cas d'une copie n'est pas ce que vous voulez. Appel d'un constructeur de clone() serait problématique car cela casserait l'héritage dans le cas d'une sous-classe veut ajouter ses propres clonable logique; si c'était pour appeler super.clone (), on pourrait obtenir un objet de la mauvaise classe dans ce cas.

Cette approche ignore tout de la logique qui peuvent être définis dans votre constructeurs, ce qui pourrait être problématique.

Un autre problème est que toutes les sous-classes qui oubliez pas de remplacer clone() héritera automatiquement la valeur par défaut copie superficielle, qui n'est probablement pas ce que vous voulez dans le cas d'mutable état (qui seront désormais partagées entre la source et la copie).

La plupart des développeurs n'utilisent pas Clonable pour ces raisons, et tout simplement de mettre en œuvre un constructeur de copie à la place.

Pour plus d'informations et les pièges potentiels de Clonable, je recommande fortement le livre Efficace Java par Joshua Bloch

13voto

Vladimir Ivanov Points 23731
  1. Le clonage invoque une manière extralinguistique de construire des objets - sans constructeur.
  2. Le clonage nécessite que vous traitiez d'une manière ou d'une autre avec CloneNotSupportedException - ou que vous gêniez le code client pour le traiter.
  3. Les avantages sont minimes - vous n'avez pas à écrire manuellement un constructeur de copie.

Alors, utilisez Judiosly Cloneable. Cela ne vous donne pas suffisamment d'avantages par rapport aux efforts que vous devez faire pour bien faire.

10voto

Charles Points 295

Le clonage est un paradigme de programmation. Le fait que Java peut avoir mis en œuvre mal dans beaucoup de façons de ne pas du tout diminuer le besoin de clonage. Et, il est facile à mettre en œuvre le clonage qui fonctionnera, toutefois, vous voulez que cela fonctionne, peu profond, profond, mixte, que ce soit. Vous pouvez même utiliser le nom de clone de la fonction et de ne pas mettre en œuvre Clonable si vous le souhaitez.

Supposons que j'ai des classes A, B, et C, où B et C sont des dérivés de A. Si j'ai une liste d'objets de type A comme ceci:

ArrayList<A> list1;

Maintenant, cette liste peut contenir des objets de type A, B ou C. Vous ne savez pas quel type les objets. Donc, vous ne pouvez pas copier la liste comme ceci:

ArrayList<A> list2 = new ArrayList<A>();
for(A a : list1) {
    list2.add(new A(a));
}

Si l'objet est en fait de type B ou C, vous n'aurez pas le droit de copie. Et, si l'Un est abstrait? Maintenant, certaines personnes ont suggéré ceci:

ArrayList<A> list2 = new ArrayList<A>();
for(A a : list1) {
    if(a instanceof A) {
        list2.add(new A(a));
    } else if(a instanceof B) {
        list2.add(new B(a));
    } else if(a instanceof C) {
        list2.add(new C(a));
    }
}

C'est une très, très mauvaise idée. Si vous ajoutez un nouveau type dérivé? Que faire si B ou C sont dans un autre paquet, et vous n'avez pas accès à cette classe?

Ce que vous voulez faire est ceci:

ArrayList<A> list2 = new ArrayList<A>();
for(A a : list1) {
    list2.add(a.clone());
}

Beaucoup de personnes ont indiqué pourquoi la base Java mise en œuvre de clone est problématique. Mais, il est facilement surmonter cette façon:

Dans la classe A:

public A clone() {
    return new A(this);
}

Dans la classe B:

@Override
public B clone() {
    return new B(this);
}

Dans la classe C:

@Override
public C clone() {
    return new C(this):
}

Je ne suis pas la mise en œuvre de Clonable, juste en utilisant le même nom de fonction. Si vous n'aimez pas que, nom de quelque chose d'autre.

5voto

ILMTitan Points 5095

A) Il n'y a pas beaucoup d'avantages de clone sur un constructeur de copie. Probablement le plus grand est la possibilité de créer un nouvel objet du même type dynamique (en supposant que le type déclaré est clonable et dispose d'un clone de la méthode).

B) La valeur par défaut clone crée une copie superficielle, et il restera une copie à moins que votre clone de mise en œuvre de changements. Cela peut être difficile, surtout si votre classe a final champs

Bozho est droit, le clone peut être difficile d'obtenir le droit. Un constructeur de copie/d'usine de servir à la plupart des besoins.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X