Implementierung von clone() für unveränderliche Klassen
Ich bin die Entwicklung einer Klassenbibliothek.
- Ich habe eine abstrakte Basisklasse Matrix für Matrizen, bietet Implementierungen für einige der grundlegenden Methoden.
- Abgeleitet von Matrix sind konkrete Unterklassen für verschiedene Arten von Matrizen.
- Ich habe die Anforderung für Matrizen werden cloneable, so Matrix implementiert das Cloneable-interface.
- Einige der Klassen, abgeleitet von Matrix sind unveränderlich
Wäre es akzeptabel für das immutable-Klassen' - Klon-Methoden, anstatt ein Klon des Objekts, wird das Objekt selbst zurückgegeben?
Einige (vereinfachte) code zur Klarstellung:
abstract class Matrix implements Cloneable {
...
}
class ImmutableMatrix extends Matrix {
ImmutableMatrix clone() {
return this;
}
...
}
class SomeOtherMatrix extends Matrix {
SomeOtherMatrix clone() {
SomeOtherMatrix other = super.clone();
...
return other;
}
...
}
- Warum erlauben es sogar, dass Ihre Objekte geklont werden, die in den ersten Platz?
- Einige Operationen (wie transposition) können problemlos implementiert werden, indem du ein kleines wrapper um die ursprüngliche matrix und die Berechnung der Werte on-the-fly. Sie können auch reduzieren den Speicherbedarf in einigen Situationen (z.B. Operationen auf große, dünnbesetzte Matrizen). Das funktioniert gut, solange die ursprüngliche matrix ist unveränderlich. Sonst irgendwelche änderungen an der ursprünglichen matrix und haben Nebenwirkungen auf das Ergebnis. Aber habe ich jetzt gelöst durch die Bereitstellung einer getImmutable () - Methode, die für unveränderliche Unterklassen nur gibt das Objekt selbst, während veränderlich Unterklassen Rückkehr eine unveränderliche Kopie. Nicht mehr Klonen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hätte ich gedacht aufrufen
super.clone()
ausreichen würde.Wenn Ihre Klasse ist unveränderlich, dann sollte es schon geklonte alle mutable Klassen, wenn es gebaut wurde. Ich würde daher denken, es wäre sicher zu haben flache Kopien alle Felder Ihrer Klasse hat.
Die JavaDocs Staat, der
x.clone() != x
bevorzugt. Zwar ist dies nicht eine absolute Voraussetzung, wäre es sicherlich verletzt, indem Sie Ihren plan einfach zurückthis
.Nur zurück
this
in der clone () - Implementierung von unveränderlichen Klassen.Während Sie könnte haben das immutable-Klassen einfach zu implementieren
clone
zurück Verweise auf sich selbst, ich wirklich don ' T sehen viel Wert in die Verwendungclone
auf Dinge, die möglicherweise oder möglicherweise nicht veränderbar, fehlen einige Weg zu machen, wandelbar ist, meistert der unveränderlichen Dinge und Umgekehrt.Ich würde denken, es wäre besser für Ihre Basis
Matrix
- Klasse um MethodenIsImmutable
undIsWritable
zusammen mitAsImmutable
,AsMutable
, undAsNewMutable
Methoden; es sollte auch Methoden zum Lesen und schreiben der matrix (wenn das aufrufen des "write" - Methode auf nicht-schreibbaren matrix sollte eine Ausnahme werfen).Definieren statische Methoden
CreateImmutableMatrix
undCreateMutableMatrix
was angesichts einerMatrix
eine neue unveränderlich oder veränderlich-matrix, die zuvor initialisiert mit den richtigen Daten.Mutable Klassen implementieren sollte
AsImmutable
zu geben sich zuCreateImmutableMatrix
,AsMutable
zurück sich selbst, undAsNewMutable
zu geben sich zuCreateMutableMatrix
.Unveränderliche Klassen implementieren sollte
AsImmutable
zurückzukehren, selbstAsMutable
zu nennenAsNewMutable
, undAsNewMutable
zu geben sich zuCreateMutableMatrix
.Nur-lese-Wrapper zu implementieren sollte
AsImmutable
zu nennenAsImmutable
auf den verpackten Objekten, undAsMutable
undAsNewMutable
zu nennenAsNewMutable
auf den verpackten Objekten.Ein Objekt erhält eine matrix, die es kann oder kann nicht kopieren oder mutieren können Sie einfach speichern Sie es in einem Feld (z.B.
Foo
). Wenn es braucht, zu mutieren, die matrix, kann es zu ersetzenFoo
mitFoo.AsMutable()
. Wenn das Objekt mit der matrix kopiert werden muss, wird das Feld ersetzt werden soll, die Kopie mit entwederFoo.AsImmutable()
oderFoo.AsNewMutable()
je nachdem, ob das Feld in der Kopie müssen wahrscheinlich mutiert.AsNewMutable
undAsImmutable
, aber ich bin mir nicht sicher überAsMutable.
Würde nicht aufrufen wie eine Methode, die auf ein veränderliches Objekt geben an, dass Sie sich hätte übergeben das Objekt als veränderlich version trotzdem? Der Aufruf dieser Methode auf ein Objekt impliziert, dass Sie möglicherweise Nebenwirkungen haben oder Sie möglicherweise nicht.AsMutable
auf Referenzen, die waren garantiert entweder (1) unveränderlich sind, oder (2) halten Sie das nur den Verweis in das Universum, um das veränderliche Objekt in Frage-wahrscheinlich eine, die produziert wurde, durch den Aufruf "AsMutable" auf ein immutable-Objekt und die noch nicht freigegeben da. AufrufAsNewMutable
auf dem Universum ist nur die Referenz auf ein veränderliches Objekt arbeiten würde, aber es wäre unnötig langsam. Ob der code ein Objekt Klonen mit z.B. zehn "teuren" Eigenschaften, und es ist wahrscheinlich, dass nur ein oder zwei brauchen, um geändert werden, bevor...AsImmutable
wenn Sie die Eigenschaften und dann mitAsMutable
Wann man es ändern muss, Sie würde am Ende produzieren Sie eine extra-Kopie aller Sachen, die mutierte, bevor das Objekt geklont wurde wieder, aber würde die Notwendigkeit vermeiden, um neue Kopien von Dingen, die nicht geändert werden. Dies kann einen großen Unterschied in der Effizienz, insbesondere bei der Verwendung von verschachtelten Sammlungen. Wenn z.B. eine Sammlung aus zehn Knoten, die halten zehn Elemente, sowie je zwei Blatt-Knoten verändert werden, die zwischen Klonen Operationen, Verwendung vonAsImmutable
auf den Klon und dieAsMutable
wenn...AsNewImmutable
für alles würde bedeuten, dass die änderungen wäre nicht erforderlich, alle kopieren, aber die nächsten cloning-Vorgang kopieren müsste alle 100-Blatt-Knoten und alle 10 mid-level-Knoten. MitAsMutable
würde so drehen 110 kopieren Operationen in vier.AsNewImmutable
im letzten Beitrag ein Schreibfehler?)Ihrer Klasse ist nicht unbedingt unveränderlich, da es nicht endgültig ist: es kann veränderlich Unterklassen.
Wenn jemand will, um eine Unterklasse
ImmutableMatrix
ist, wird er nicht in der Lage sein zu implementierenclone()
durch den Aufrufsuper.clone()
wenn Sie gerade zurückthis
. So in diesem Fall sollten Sie anrufensuper.clone()
.Jedoch, wenn Sie Ihre Klasse Finale, ich sehe keinen Grund, warum nicht einfach zurück
this
.clone
einfachreturn this;
. Wenn eine Klasse angegeben ist, die durch Vertrag werden unveränderlich, nachdem die Umsetzungclone
alsreturn this
können akzeptabel sein, auch wenn die Klasse ist vererblich, sofern der Vertrag Dokumente, die abgeleitete Klassen können nicht rechtmäßig tun, würde alles, was Klone zu unterscheiden.Ja, Wenn wir sehen das Verhalten von Strings (Immutable class), Wenn die Inhalte gleich sind und dasselbe Objekt zurückgegeben, so dass ich, was Ihre Recht sind , clone () - Methode sollte nur zurückgeben.
getImmutable()
- Methode der matrix-Klasse und verwenden, statt. Das spart mir aus das erstellen von unnötigen Klone für unveränderliche Klassen, während die veränderlichen Klassen können eigene Implementierung dieser Methode durch die Schaffung eine unveränderliche Kopie der matrix.