Flache Kopie eines Objektes - warum so kompliziert?



  • Guten Tag!

    Ich beschäftige mich erst seit kurzem mit Java und habe festgestellt, dass es nicht
    ohne weiteres möglich ist, eine flache Kopie eines Objektes zu erstellen...
    (im Gegensatz zu C++!)

    Folgendes Testprogramm:

    /* Test.java */
    
    class Blubb
    implements Cloneable
    {
            private int foo;
            private double bar;
    
            public Blubb(int foo, double bar)
            {
                    this.foo = foo;
                    this.bar = bar;
            }
    
            public Object clone()
            {
                    try {
                            Blubb cloned = (Blubb)super.clone();
                            return cloned;
                    } catch(Exception e) {
                            throw new InternalError(e.toString());
                    }
            }
    }
    
    public class Test
    {
            public static void main(String[] args)
            {
                    Blubb test1 = new Blubb(5, 10);
                    Blubb test2 = (Blubb)test1.clone();
            }
    }
    

    Muss man denn wirklich das Cloneable Interface implementieren (und dann auch
    noch so kompliziert mit "Herumgecaste"), nur um ein flache Kopie eines
    Objektes zu erstellen? 🙄

    gruß,
    walker


  • Mod

    walker schrieb:

    Muss man denn wirklich das Cloneable Interface implementieren (und dann auch
    noch so kompliziert mit "Herumgecaste"), nur um ein flache Kopie eines
    Objektes zu erstellen? 🙄

    Cloneable sollte man eher meiden. Ich empfehle, einen Copy-Konstruktor zu schreiben, wenn man ihn braucht.



  • Warum? Und wie soll das mit Polymorphie zusammen funktionieren?


  • Mod

    Bashar schrieb:

    Warum?

    Um clone und Cloneable richtig anzuwenden muss man einen relativ komplizierten, dürftigen Vertrag einhalten, der schlecht dokumentiert ist. Der Mechanismus, mit dem dann das Objekt erzeugt wird, ist zudem relativ kompliziert. Hier kommen mal einige diesbezügliche Stellen aus "Effektiv Java Programmieren":

    Wenn sie ein Interface implementieren, sagen Sie dadurch normalerweise etwas darüber aus, was eine Klasse für ihre Clients tun kann. Bei Cloneable hingegen ändern Sie dadurch das Verhalten einer geschützten Methode in einer Oberklasse.

    Damit die Implementierung des Interface Cloneable sich auf eine Klasse auswirkt, müssen die Klasse und alle ihre Oberklassen ein relativ komplexes, nicht erzwingbares und größtenteils nicht dokumentiertes Protokoll einhalten. Dadurch ergibt sich ein außersprachlicher Mechanismus: Dieser erzeugt ein Objekt, ohne einen Konstruktor aufzurufen.

    Der allgemeine Vertrag der Methode clone ist dürftig.

    In der Praxis erwartet man von einer Klasse, die Cloneable implementiert, dass sie eine ordentlich funktionierende öffentliche clone-Methode bereitstellt. Normalerweise ist dies nur dann möglich, wenn alle Oberklassen der Klasse eine öffentliche oder geschützte clone-Implementierung mit gutem Verhalten bereitstellen.

    Die clone-Architektur ist mit der normalen Benutzung von final-Feldern, die sich auf veränderliche Objekte beziehen, nicht vereinbar.

    Wenn Sie eine Klasse erweitern, die Cloneable implementiert, haben Sie gar keine andere Wahl als eine clone-Methode mit gutem Verhalten zu implementieren.

    Bashar schrieb:

    Und wie soll das mit Polymorphie zusammen funktionieren?

    Interessantes Problem. Vermutlich muss man das dann mit Hilfe von Reflection lösen.


Anmelden zum Antworten