Heim >Java >javaLernprogramm >Deep-Copy- und Shallow-Copy-Methoden der Java Cloneable-Schnittstelle

Deep-Copy- und Shallow-Copy-Methoden der Java Cloneable-Schnittstelle

PHPz
PHPznach vorne
2023-04-28 08:49:131243Durchsuche

    Klonbarer Schnittstellenquellcode

    Klonbare Schnittstelle:

    Die Klasse, die diese Schnittstelle implementiert – daraus kann abgeleitet werden, dass die Methode clone() legal aufgerufen werden kann –, um Klasseninstanzen zu implementieren: Attribut-zu-Attribut kopieren. java.lang.Object

    Wenn eine Klasse die Cloneable-Schnittstelle nicht implementiert, wird beim Aufruf der clone()-Methode eine CloneNotSupportedException ausgelöst.

    Im Allgemeinen

    Unterklassen, die die Cloneable-Schnittstelle implementieren, sollten die clone()-Methode mit öffentlichem Zugriff überschreiben (obwohl die Clone-Methode in der Klasse java.Object vom geschützten Typ ist)

    Es sollte beachtet werden, dass dies bei der Cloneable-Schnittstelle nicht der Fall ist Schließen Sie die Methode clone() ein. Wenn Sie also nur die Schnittstelle Cloneable implementieren, können Sie das Objekt nicht normal klonen

    [Grund: Selbst wenn die Methode clone reflektierend aufgerufen wird, gibt es keine Garantie dafür, dass sie erfolgreich ist]&ndash ;–Persönlich Das Verständnis ist:

    Es wird dadurch verursacht, ob die Clone()-Methode überschrieben werden soll oder das Problem von „flacher Kopie und tiefer Kopie“.

    class Pet implements Cloneable{
        //properties
        private String name;
        public void setName(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
        public Pet() {
        }
        public Pet(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Pet{" +
                    "name='" + name + '\'' +
                    '}';
        }
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pet pet = (Pet) o;
            return Objects.equals(name, pet.name);
        }
        @Override
        public int hashCode() {
            return Objects.hash(name);
        }
    //    @Override
    //    public Pet clone() {
    //        try {
    //            return (Pet)super.clone();
    //        } catch (CloneNotSupportedException e) {
    //            e.printStackTrace();
    //        }
    //        return null;
    //    }
    }

    Flacher Kopierfall

    Pet-Klassendefinition

    Hinweis: Die Pet-Klasse implementiert die Cloneable-Schnittstelle, überschreibt jedoch nicht die Clone()-Methode (offensichtlich: Die Pet-Klasse verfügt derzeit nicht über die Fähigkeit, Objekte zu klonen ).

    class Pet implements Cloneable{
        //properties
        private String name;
        public void setName(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
        public Pet() {
        }
        public Pet(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Pet{" +
                    "name='" + name + '\'' +
                    '}';
        }
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pet pet = (Pet) o;
            return Objects.equals(name, pet.name);
        }
        @Override
        public int hashCode() {
            return Objects.hash(name);
        }
    //    @Override
    //    public Pet clone() {
    //        try {
    //            return (Pet)super.clone();
    //        } catch (CloneNotSupportedException e) {
    //            e.printStackTrace();
    //        }
    //        return null;
    //    }
    }

    Person-Klassendefinition

    Hinweis: Die Person-Klasse implementiert die Cloneable-Schnittstelle und überschreibt auch die Clone()-Methode. Hat die Person-Klasse also die Möglichkeit, Objekte zu klonen? (Aufgrund des Problems des flachen Kopierens wird diese Funktion zum Klonen von Objekten als unvollständig und fehlerhaft angesehen.)

    class Pet implements Cloneable{
        //properties
        private String name;
        public void setName(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
        public Pet() {
        }
        public Pet(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Pet{" +
                    "name='" + name + '\'' +
                    '}';
        }
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pet pet = (Pet) o;
            return Objects.equals(name, pet.name);
        }
        @Override
        public int hashCode() {
            return Objects.hash(name);
        }
    //    @Override
    //    public Pet clone() {
    //        try {
    //            return (Pet)super.clone();
    //        } catch (CloneNotSupportedException e) {
    //            e.printStackTrace();
    //        }
    //        return null;
    //    }
    }

    Problem mit flachem Kopieren – Codetest

    Warum sagen Sie: Die Fähigkeit zum Klonen von Objekten der Person-Klasse ist derzeit unvollständig und fehlerhaft? Denn zu diesem Zeitpunkt, wenn die clone()-Methode über das Person-Objekt aufgerufen und das Objekt geklont wird, ist der Klon des Werts seines Mitgliedsattributs pet (ein Objekt der Pet-Klasse) nur eine einfache Kopie der Speicheradresse im Heap-Bereich.

    Das heißt: Um es ganz klar auszudrücken: Der Pet-Attributwert des Person-Objekts und des geklonten Objekts teilen sich denselben Heap-Bereichsspeicher. Das Problem liegt auf der Hand: Wenn das Haustierattribut des geklonten Objekts festgelegt ist, wirkt sich dies offensichtlich auf den Haustierattributwert des ursprünglichen Personenobjekts aus.

    Die Codedemonstration lautet wie folgt:

      //methods
        public static void main(String[] args) throws CloneNotSupportedException {
            testPerson();
        }
        public static void testPerson() throws CloneNotSupportedException {
            Person p=new Person("张三",14,new Pet("小黑"));
            System.out.println(p);
            Person clone = (Person)p.clone();
            System.out.println(clone);
            System.out.println(p.equals(clone));
            System.out.println(p.getPet()==clone.getPet());
            System.out.println("************");
            clone.setAge(15);
            System.out.println(p);
            System.out.println(clone);
            System.out.println(p.equals(clone));
            System.out.println("************");
            clone.getPet().setName("小黄");
            System.out.println(p);
            System.out.println(clone);
            System.out.println(p.equals(clone));
            System.out.println(p.getPet()==clone.getPet());
        }

    Deep-Copy- und Shallow-Copy-Methoden der Java Cloneable-Schnittstelle

    Deep Copy-Fall

    Also, wie implementiert man Deep Copy? Der Schlüssel liegt im obigen Fall in den kommentierten Codezeilen.

    Die Pet-Klasse überschreibt die clone()-Methode.

    Deep-Copy- und Shallow-Copy-Methoden der Java Cloneable-Schnittstelle

    Die clone()-Methode der Person ruft die Clone-Methode von Pet auf :

    Deep-Copy- und Shallow-Copy-Methoden der Java Cloneable-Schnittstelle

    Das obige ist der detaillierte Inhalt vonDeep-Copy- und Shallow-Copy-Methoden der Java Cloneable-Schnittstelle. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Stellungnahme:
    Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen