ホームページ >Java >&#&チュートリアル >Java Cloneable インターフェイスのディープ コピーおよびシャロー コピー メソッド
クローン可能なインターフェイス:
このインターフェイスを実装するクラスは次のとおりです。 java.lang.Object
の clone() メソッドは、クラス インスタンス、つまりプロパティ間のコピーを実装するために、合法的に呼び出すことができると推測されます。
クラスが Cloneable インターフェイスを実装していない場合、 clone() メソッドが呼び出されるときに、CloneNotSupportedException 例外がスローされます。
一般に、Cloneable インターフェースを実装する サブクラスは、パブリック アクセス許可を持つ clone() メソッド をオーバーライドする必要があります (ただし、java.Object クラスの clone メソッドは保護された型です)
Cloneable インターフェイスには clone() メソッドが含まれていないことに注意してください。したがって、Cloneable インターフェイスを実装しただけでは、オブジェクトを正常に複製することはできません。
[理由:リフレクティブに呼び出したとしても、クローン作成メソッドが成功する保証はありません] - 私の個人的な理解は次のとおりです。 Clone() メソッドをオーバーライドするかどうか、または「浅いコピーとコピー」の存在が原因です。ディープコピー」の問題。
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; // } }
注: Pet クラスは Cloneable インターフェイスを実装しますが、Clone() メソッドをオーバーライドしません (明らかに:この Pet クラスにはオブジェクトのクローンを作成する機能がありません)。
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; // } }
注: パーソン クラスは Cloneable インターフェイスを実装し、Clone() メソッドもオーバーライドします。では、 Person クラスにはオブジェクトのクローンを作成する機能があるのでしょうか? (浅いコピーの問題により、このオブジェクトのクローン作成機能は不完全で欠陥があると考えられます)。
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 クラスのオブジェクト クローン作成機能が不完全で欠陥があると言われているのはなぜですか?現時点では、 Person オブジェクトを通じて clone() メソッドが呼び出され、オブジェクトが複製されると、そのメンバー属性 pet (Pet クラスのオブジェクト) の値の複製は、メモリ アドレスの単純なコピーにすぎないためです。ヒープ領域にあります。
つまり: 率直に言うと、Person オブジェクトの pet 属性値と複製されたオブジェクトは同じヒープ領域メモリを共有します。問題は明らかです。複製されたオブジェクトの pet 属性が設定されると、元の person オブジェクトの pet 属性値に明らかに影響します。
コードのデモは次のとおりです:
//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()); }
それでは、ディープ コピーの実装方法を説明します。コピー?鍵は、上記の場合のコードのコメント行にあります。
テスト コードは変更されていないため、再度実行します:
以上がJava Cloneable インターフェイスのディープ コピーおよびシャロー コピー メソッドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。