Frage

Ich war für einige Tutorials über Java Cloneable zu erklären, aber haben keine gute Links erhalten, und Stack-Überlauf wird immer sowieso mehr offensichtliche Wahl.

Ich möchte Folgendes wissen:

  1. Cloneable bedeutet wir einen Klon oder um eine Kopie der Objekte haben kann, durch die Umsetzung der Cloneable Schnittstelle. Was sind die Vorteile und Nachteile, das zu tun?
  2. Wie geschieht das rekursive Klonen, wenn das Objekt a Verbundobjekt?
War es hilfreich?

Lösung

Das erste, was Sie über Cloneable wissen sollten ist, -. Nicht verwenden

Es ist sehr schwer zu implementieren mit Cloneable Recht des Klonen und die Mühe nicht wert.

Statt dessen Verwendung einige andere Optionen, wie Apache-Commons SerializationUtils (deep-Klon) oder BeanUtils (shallow-Klon) oder einfach eine Kopie-Konstruktor verwenden.

hier sehen für die Ansichten von Josh Bloch etwa mit Cloneable Klonen, was erklärt, die viele Nachteile des Ansatzes. ( Joshua Bloch ein Sun Mitarbeiter war, und führte die Entwicklung zahlreicher Java-Funktionen.)

Andere Tipps

klonbar selbst ist leider nur ein Marker-Interface, das heißt:. Es nicht die Methode clone () nicht definiert

Was tut, ist das Verhalten des geschützten Object.clone ändern () -Methode, die eine CloneNotSupportedException für Klassen werfen, die nicht klonbar implementieren und Mitglied weise flache Kopie für Klassen durchführen, die zu tun.

Auch wenn dies ist das Verhalten dem Sie suchen, werden Sie noch benötigen, um Ihre eigene Methode clone () zu implementieren, um sie öffentlich zu machen.

Wenn Sie Ihre eigenen Klon Umsetzung (), ist die Idee, mit dem Ziel zu starten, indem super.clone erstellen (), die garantiert der richtigen Klasse sein, und dann tun, um jede zusätzliche Bevölkerung von Feldern, falls eine flache Kopie ist nicht das, was Sie wollen. Aufruf eines Konstruktor von clone () wäre problematisch, da dieses Erbe im Falle einer Unterklasse ihre eigene zusätzliche klonbar Logik will brechen würde hinzuzufügen; wenn es nennt super.clone (), so wäre es eine Aufgabe der falschen Klasse in diesem Fall erhalten.

Dieser Ansatz umgeht jede Logik, die in Ihrem Konstrukteurs definiert werden, obwohl, die möglicherweise problematisch sein könnten.

Ein weiteres Problem ist, dass alle Unterklassen, die außer Kraft zu setzen Klon vergessen () automatisch erben Standard flache Kopie, die wahrscheinlich nicht das, was Sie im Falle von wandelbaren Zustand wollen (die zwischen der Quelle wird nun geteilt und die Kopie).

Die meisten Entwickler nicht verwenden klonbar aus diesen Gründen, und einfach eine Kopie Konstruktor implementieren statt.

Weitere Informationen und mögliche Gefahren von klonbar, ich das Buch Effective Java von Joshua Bloch sehr empfehlen

  1. Cloning ruft eine außersprachlichen Art und Weise Objekte zu konstruieren - ohne Konstrukteure.
  2. Klonen erfordert, dass Sie die Behandlung irgendwie mit CloneNotSupportedException -. Oder Client-Code stören sie für die Behandlung von
  3. Vorteile sind klein - Sie haben einfach nicht manuell kopieren Konstruktor schreiben
  4. .

So verwenden klonbar umsichtig. Es gibt Ihnen nicht genügend Vorteile im Vergleich zu dem Aufwand Sie alles richtig anwenden müssen tun.

Das Klonen ist eine grundlegende Programmierparadigma. Die Tatsache, dass Java es schlecht in vielerlei Hinsicht umgesetzt hat, kann gar nicht die Notwendigkeit für das Klonen zu verringern. Und es ist einfach zu implementieren, dass das Klonen funktioniert aber Sie sie haben wollen Arbeit, flach, tief, gemischt, was auch immer. Sie können sogar den Namen Klon für die Funktion verwenden und nicht implementieren klonbar wenn Sie so wollen.

Angenommen, ich habe die Klassen A, B und C, wobei B und C von A. ableiten Wenn ich eine Liste von Objekten des Typs A wie folgt aussehen:

ArrayList<A> list1;

Nun, das Liste Behälter enthält Objekte vom Typ A, B oder C. Sie wissen nicht, welche Art der Objekte sind. So können Sie die Liste wie diese nicht kopieren:

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

Wenn das Objekt tatsächlich vom Typ B oder C ist, werden Sie nicht die richtige Kopie erhalten. Und was ist, wenn A ist abstrakt? Nun haben einige Leute dies vorgeschlagen:

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));
    }
}

Dies ist eine sehr, sehr schlechte Idee. Was passiert, wenn Sie einen neuen abgeleiteten Typ hinzufügen? Was passiert, wenn B oder C ist in einem anderen Paket, und Sie haben keinen Zugang zu ihnen in dieser Klasse?

Was Sie tun möchten, ist dies:

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

Viele Menschen haben gezeigt, warum die grundlegende Java-Implementierung von Klon problematisch ist. Aber es ist leicht auf diese Weise überwunden:

In der Klasse A:

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

In der Klasse B:

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

In der Klasse C:

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

Ich bin klonbar nicht Implementierung nur die gleiche Funktion Namen. Wenn Sie wie das nicht tun, nennen Sie es etwas anderes.

A) Es gibt nicht eine ganze Menge Vorteile des Klons über einen Copy-Konstruktor. Wahrscheinlich die größte ist die Fähigkeit, ein neues Objekt des exakt gleichen dynamischen Typs zu erstellen (unter der Annahme des deklarierte Typ clonable ist und eine öffentliche Klon-Methode).

B) Die Standard-Klon erzeugt eine flache Kopie, und es wird eine flache Kopie bleiben, es sei denn Ihre Klon Implementierung das ändert. Dies kann schwierig sein, vor allem, wenn Ihre Klasse hat letzte Felder

Bozho richtig ist, kann Klon schwierig sein, richtig zu machen. Eine Kopie Konstruktor / Fabrik werden die meisten Bedürfnisse dienen.

Was sind Nachteile klonbar?

Das Klonen ist sehr gefährlich, wenn das Objekt, den Sie kopieren composition.You Bedarf hat etwa unterhalb möglicher Nebenwirkung in diesem Fall zu denken, weil Klon flache Kopie erstellt:

Lassen Sie uns sagen, dass Sie ein Objekt haben DB ähnliche Manipulation zu handhaben. Sagen Sie, dass das Objekt Connection Objekt als eines der Eigenschaft hat.

Also, wenn jemand Klon von originalObject erstellt, das Objekt erstellt wird, sagen wir mal, cloneObject. Hier ist die originalObject und cloneObject halten die gleiche Referenz für Connection Objekt.

Lassen Sie sagen originalObject schließt das Connection Objekt, so dass nun die cloneObject wird nicht funktionieren, weil die connection Objekt wurde zwischen ihnen geteilt und es wurde actaually durch die originalObject geschlossen.

Ein ähnliches Problem kann auftreten, wenn wir sagen, dass Sie ein Objekt klonen möchten, die Iostream als Eigenschaft hat.

Wie funktioniert das rekursive Klonen passieren, wenn das Objekt ein zusammengesetztes Objekt ist?

klonbar führt flache Kopie. Bedeutung ist, dass Daten des Originalobjekts und Klon-Objekt auf die gleiche Referenz / Speicher verweisen. Gegenteil im Fall von tiefer Kopie, Daten aus dem Speicher des ursprünglichen Objekts in den Speicher des Klons Objekts kopiert wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top