Clone-Methode vs Kopie Konstruktor in Java. Welche ist die richtige Lösung? Wo soll jeder Fall verwendet werden?Clone() vs Copy-Konstruktor - was in Java empfohlen wird
Antwort
Klon ist kaputt, also benutzen Sie es nicht.
die Clone-Methode der Object-Klasse ist eine etwas magische Methode, die tut, was keine reine Java-Methode jemals tun konnte: Es eine identische Kopie von sein Objekt erzeugt. Es war in der Primordial Object Superklasse seit der Beta-Release-Tage der Java Compiler *; und es, wie alle alten Magie, erfordert die entsprechende incantation den Zauber von unerwartet zu verhindern backfiring
Bevorzugen Sie eine Methode, die kopiert das Objekt
Foo copyFoo (Foo foo){
Foo f = new Foo();
//for all properties in FOo
f.set(foo.get());
return f;
}
Lesen Sie mehr http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspx
Um, Klon ist nicht gebrochen. Warum denkst du ist es? Wenn es ist, weil es nicht funktioniert, wenn Sie es nicht überschreiben - nun, das ist sein Vertrag. – Bozho
@Bozho, lesen _Effective Java 2nd Edition_, erklärte Bloch es ziemlich gut. Doug Lea benutzt 'klon()' nicht mehr, außer um Arrays zu klonen (http://www.artima.com/intv/bloch13.html). – polygenelubricants
Ich verstehe nicht wirklich, warum das Klonen nicht einfacher sein kann. Ist das eine Wahl? oder dahinter stehen wirklich harte Probleme? – LB40
Bedenken Sie, dass clone()
nicht out of the box funktioniert. Sie müssen Cloneable
implementieren und die clone()
-Methode außer Kraft setzen, die in public
macht.
Es gibt ein paar Alternativen, die bevorzugt sind (da die clone()
Methode hat viele Design-Fragen, wie in anderen Antworten angegeben), und die Kopie-Konstruktor würde erfordern Handarbeit:
BeanUtils.cloneBean(original)
schafft ein oberflächlicher Klon, wie der vonObject.clone()
erzeugte. (Diese Klasse ist von commons-beanutils)SerializationUtils.clone(original)
erstellt einen tiefen Klon. (Dh die ganze Eigenschaften Graph geklont wird, nicht nur die erste Ebene) (von commons-lang), aber alle Klassen implementieren müssenSerializable
Java Deep Cloning Library tief Klonen bietet, ohne die Notwendigkeit
Serializable
Wie funktioniert diese tiefe Klon-Bibliothek an einem Objekt? Ich rieche Code, der wahrscheinlich mit Reflexion gespickt ist – Cruncher
ja, eine Menge Reflexion :) – Bozho
welche von diesen kopiert keine Referenzen und kopieren nach Werten? BeanUtils.cloneBean (Bean) kopiert Referenzen, aber ich verwende eine Android-Version (android-java-air-bridge.jar) nicht original Apache-Version. –
Siehe auch umzusetzen : How to properly override clone method?. Klonen ist in Java gebrochen, es ist so hart, um es richtig zu machen, und selbst wenn es tut bietet nicht wirklich viel, so ist es nicht wirklich die Mühe wert.
Es ist viel einfacher, mit einer 'finalen' Klasse, die von' java.lang.Object' erbt, richtig zu kommen. Es ist schwierig, wenn die Klasse veränderbare Datenstrukturen enthält (und somit eine Deepcopy erfordert), aber die gleiche Herausforderung würde sich auch in einem Kopierkonstruktor ergeben. – IceArdor
Beachten Sie, dass der Kopierkonstruktor den Klassentyp auf den des Kopierkonstruktors beschränkt. Betrachten Sie das Beispiel:
// Need to clone person, which is type Person
Person clone = new Person(person);
Das funktioniert nicht, wenn person
eine Unterklasse von Person
sein könnte (oder wenn Person
ist eine Schnittstelle). Das ist der springende Punkt von Klon, dass es den richtigen Typ zur Laufzeit dynamisch klonen kann (vorausgesetzt, Klon ist korrekt implementiert).
Person clone = (Person)person.clone();
oder
Person clone = (Person)SomeCloneUtil.clone(person); // See Bozho's answer
Jetzt können person
jede Art von Person
unter der Annahme, dass clone
richtig umgesetzt wird.
Es ist bedauerlich, dass jemand einmal vorgeschlagen hat, dass eine korrekte Implementierung des Klons "new" statt "super.clone()" beinhalten sollte, da das richtige Verhalten für 'clone' darin besteht, 'super.clone()' aufzurufen, wenn diese Methode selbst verwendet wird ruft 'super.clone()' auf (oder ist der integrierte Memberwise-Klon für ein Objekt); Wenn 'super.clone()' schließlich 'new' aufruft, ist das einzige, nicht völlig durchgebrochene Verhalten für' clone() ',' 'new'' selbst zu nennen, aber dann muss jede untergeordnete Klasse 'clone()' überschreiben Machen Sie ebenfalls, ob die Kindklasse sonst 'clone()' überschreiben müsste. – supercat
Die Frage "tief gegen flach" erscheint mir in den meisten Fällen nicht mehrdeutig. Eine 'SomeCollection
clone() wurde mit mehreren Fehlern erstellt (siehe this question), also vermeiden Sie es am besten.
Von Effective Java 2nd Edition, Punkt 11: Überschreiben von Klon umsichtig
alle Probleme im Zusammenhang mit klonbar Gegeben, ist es sicher zu sagen, dass andere Schnittstellen nicht verlängern sollte, und dass für Vererbung entworfen Klassen (Artikel 17) sollte es nicht umsetzen. Wegen seine vielen Mängel, wählen einige Experten Programmierer einfach nie überschreiben die Klon-Methode und nie, um es außer vielleicht, um kopieren Arrays. Wenn Sie eine Klasse für die Vererbung entwerfen, beachten Sie, dass Sie keine geschützte Klonmethode bereitstellen möchten. Daher ist für Unterklassen nicht möglich, Cloneable zu implementieren.
Dieses Buch beschreibt auch die vielen Vorteile, die Kopierkonstrukteure über Cloneable/Clone haben.
- Sie stützen sich nicht auf risikobehaftete außerObjektErstellung Mechanismus
- Sie verlange nicht nicht durchsetzbar Einhaltung dünn dokumentiert Konventionen
- Sie mit den richtigen Gebrauch der endgültigen Felder nicht in Konflikt geraten
- Sie werfen keine unnötigen geprüften Ausnahmen
- Sie benötigen keine Umwandlungen.
Alle Standardsammlungen verfügen über Kopierkonstruktoren. Benutze sie.
List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original);
Sie kopieren 'original' als 'ArrayList', wenn es sich um einen anderen Listentyp gehandelt haben könnte (z. B.' LinkedList'). Aus diesem Grund ist Klon besser als ein Kopierkonstruktor. –
Große Traurigkeit: weder klonbar/Klon noch ein Konstruktor sind große Lösungen: ICH WILL NICHT die implementierende Klasse WISSEN !!! (z. B. - Ich habe eine Map, die kopiert werden soll, mit der gleichen versteckten MumbleMap-Implementierung) Ich möchte nur eine Kopie erstellen, wenn dies unterstützt wird. Aber leider hat Cloneable nicht die clone-Methode, also gibt es nichts, auf das Sie clone() sicher tippen können.
Was auch immer die beste "Kopierobjekt" -Bibliothek da draußen ist, Oracle sollte sie zu einer Standardkomponente der nächsten Java-Version machen (es sei denn, sie ist bereits irgendwo versteckt).
Natürlich, wenn mehr der Bibliothek (z. B. - Sammlungen) unveränderlich wäre, würde diese "Kopie" Aufgabe einfach weggehen. Aber dann würden wir anfangen, Java-Programme mit Dingen wie "Klasseninvarianten" anstatt dem verdammten "Bohnen" -Muster zu entwerfen (ein zerbrochenes Objekt machen und mutieren, bis es gut genug ist).
Es gibt * einige * Hoffnung für diese Art von Sache, zumindest für Wertobjekte, die Sie in Ihrem Projekt machen: https://projectlombok.org/features/experimental/Wither.html – Roboprog
Wenn das Kopieren einfach wäre, hätte es das schon war Teil von Java. Aber es ist nicht. Möchten Sie eine flache Kopie, eine tiefe Kopie oder irgendwo dazwischen? Haben Sie unterschiedliche Verhaltensweisen für verschiedene Klassen, abhängig davon, was Sie kopieren und woran Sie arbeiten? Was passiert mit Generika? Was passiert, wenn das, was du kopierst, ein Parameter für ein Generic ist? Dies könnte ein wenig einfacher zu verstehen sein, ohne Vererbung und ohne Veränderbarkeit, aber diese sind in das Herz von Java (die Sprache) eingebacken. Vielleicht erleichtert eine Sprache wie Scala, die Garantien über die Veränderbarkeit gibt, die Klonbarkeit. – IceArdor
- 1. Was Importeinstellungen in Datenbank-Projekt empfohlen wird
- 2. Node.js Versionen: Empfohlen vs Current?
- 3. Was ist "Fluid powered TYPO3" und wird es empfohlen?
- 4. In Zend Framework 2 RBAC oder ACL. Was wird empfohlen?
- 5. Warum bewegen Konstruktor statt Copykonstruktor genannt wird
- 6. Implicit Copykonstruktor
- 7. Warum Copykonstruktor wird in Aufruf aufgerufen std :: vector :: emplace_back()?
- 8. Welche Server-Software wird empfohlen, Java-basierte Webservices auszuführen?
- 9. Warum HibernateTemplate nicht empfohlen wird?
- 10. Welcher PyPy Speicherprofiler wird empfohlen?
- 11. Warum Clone-Methode in Java überschreiben
- 12. Copykonstruktor abgeleiteter QT Klasse
- 13. Implizit Copykonstruktor Aufruf
- 14. Copykonstruktor tut primitive Datentypen
- 15. DDS - Welche wird empfohlen - OpenSplice oder CoreDX?
- 16. Copykonstruktor geschweiften Klammern Initialisierung
- 17. Wird die Verschlüsselung von Javascript empfohlen?
- 18. Wird die Verwendung des Mediatormusters empfohlen?
- 19. GAE Initialisierung empfohlen Praxis
- 20. Arbeiten mit Dreamweaver und ASP.NET - wird dies empfohlen?
- 21. Warum wird empfohlen, .innerHTML zu vermeiden?
- 22. Welcher Ansatz wird empfohlen: aggregateRoot.Items.Add (...) oder aggregateRoot.AddItem (...)
- 23. Warum wird gunicorn_django nicht mehr empfohlen?
- 24. Was mache ich nach git clone --are?
- 25. Wie wird die C# -Klassenbibliothek (DLL) empfohlen?
- 26. Warum "$(). Ready (handler)" wird nicht empfohlen?
- 27. Wird ObservableCollection empfohlen, bevor Elemente hinzugefügt werden?
- 28. Wird die Legacy-Kriterien-API weiterhin empfohlen?
- 29. Clone MovieClip in Echtzeit
- 30. Gibt es Alternativen zur Implementierung von Clone in Java?
http://StackOverflow.com/Questions/1106102/Clone-VS-Copy-Constructor-VS-Factory-Method –
Vermeiden Sie "Klon" * um jeden Preis * und gehen Sie für Ihre eigene Kopierlösung. – dimitarvp
Kopieren Konstruktoren sind besser als Object.clone() weil sie Erzwingen Sie uns nicht, irgendeine Schnittstelle zu implementieren oder irgendeine Ausnahme zu werfen, aber wir können es sicher tun, wenn es erforderlich ist Benötigen Sie keine Umwandlungen, Erfordern Sie uns nicht von einem unbekannten Objekt abhängen Erstellungsmechanismus, Erfordern keine Elternklasse, um irgendeinen Vertrag zu befolgen oder irgendetwas zu implementieren, Erlauben Sie uns, letzte Felder zu modifizieren, erlauben Sie uns, die vollständige Kontrolle über die Objekterstellung zu haben, können wir unsere Initialisierungslogik darin schreiben. Lesen Sie mehr https://programmingmitra.blogspot.in/2017/01/Java-cloning-copy-constructor-versus-Object-clone-or-cloning.html –