この記事では、Java オブジェクトのシャロー クローン作成とディープ クローン作成について詳しく説明します。必要な方は参考にしてください。
オブジェクト基本クラスには、初期オブジェクトのクローンを生成する clone というメソッドがあります。参照タイプが存在する場合は、ディープ クローン作成が行われます。シャロー クローン作成とシャロー クローン作成の違いは、クローンされたオブジェクトに参照タイプの属性がある場合、ディープ クローン作成ではその属性の完全なコピーが作成されるのに対し、シャロー クローン作成では参照のみがコピーされることです。属性に。まず、簡単にできるいくつかの小さな問題を見てみましょう。
clone メソッドは Object クラスに属し、Cloneable インターフェイスは単なるマーク インターフェイスです。マーク インターフェイスはユーザー マークを使用します。クラスには、ある種のインターフェイス マーキング機能があります。Serializable、Cloneable、および RandomAccess という 3 つの一般的なマーキング インターフェイスがあります。Cloneable インターフェイスが実装されていない場合、cloneNotSupportedException 例外が発生します。
Object クラスの clone メソッドは protected で変更されます。つまり、このメソッドをサブクラスでオーバーライドしないと、この保護されたアクセス許可はサブクラス外でのみアクセスできなくなります。これにより、サブクラスは親クラスのメソッドをオーバーライドするときに権限修飾子を大きくできるが、小さくはできないというステートメントも検証されます。
protected native Object clone() throws CloneNotSupportedException;
clone メソッドを内部的にオーバーライドするのは、実際にはアクセス権を拡張するためだけであり、protected を public に変更することもできます。将来相続する場合はそうします。もちろん、これは浅いクローンのクローン機能のみであり、深いクローンの場合は変更が必要です。
@Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }
属性が String で、String もクラスである場合、String は参照型ですか? String は基本的な型と同様に動作します。つまり、複製後に 2 つの参照は同じ String を指しますが、どちらかが変更されると、String の値は変更されません。文字列が生成され、変更された参照は新しい文字列を指します。見た目はベーシックタイプと変わりません。
浅いクローンは、クラス User には、成績属性 Mark が含まれており、中国語、数学などで構成されています。浅いクローンの失敗
class Mark{ private int chinese; private int math; public Mark(int chinese, int math) { this.chinese = chinese; this.math = math; } public void setChinese(int chinese) { this.chinese = chinese; } public void setMath(int math) { this.math = math; } @Override public String toString() { return "Mark{" + "chinese=" + chinese + ", math=" + math + '}'; } } public class User implements Cloneable{ private String name; private int age; private Mark mark; public User(String name, int age,Mark mark) { this.name = name; this.age = age; this.mark = mark; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + ", mark=" + mark + '}'; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } public static void main(String[] args) throws CloneNotSupportedException { Mark mark = new Mark(100,99); User user = new User("user",22,mark); User userClone = (User) user.clone(); System.out.println("原user:"+user); System.out.println("克隆的user:"+userClone); //修改引用类型的mark属性 user.mark.setMath(60); System.out.println("修改后的原user:"+user); System.out.println("修改后的克隆user:"+userClone); } }
出力結果は次のとおりです:
元のユーザー: User{name='user', age=22, mark=Mark{chinese=100, math=99}}
クローン ユーザー: User{name='user', age=22, mark=Mark{chinese=100, math=99}}
変更された元のユーザー: User{name='user', age=22, mark = Mark{chinese=100, math=60}}
変更されたクローン ユーザー: User{name='user', age=22, mark=Mark{chinese=100, math=60}}
class Mark implements Cloneable{ private int chinese; private int math; public Mark(int chinese, int math) { this.chinese = chinese; this.math = math; } public void setChinese(int chinese) { this.chinese = chinese; } public void setMath(int math) { this.math = math; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public String toString() { return "Mark{" + "chinese=" + chinese + ", math=" + math + '}'; } } public class User implements Cloneable{ private String name; private int age; private Mark mark; public User(String name, int age,Mark mark) { this.name = name; this.age = age; this.mark = mark; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + ", mark=" + mark + '}'; } @Override protected Object clone() throws CloneNotSupportedException { User user = (User) super.clone(); user.mark = (Mark) this.mark.clone(); return user; } public static void main(String[] args) throws CloneNotSupportedException { Mark mark = new Mark(100,99); User user = new User("user",22,mark); User userClone = (User) user.clone(); System.out.println("原user:"+user); System.out.println("克隆的user:"+userClone); //修改引用类型的mark属性 user.mark.setMath(60); System.out.println("修改后的原user:"+user); System.out.println("修改后的克隆user:"+userClone); } }のネストされた呼び出しです。出力結果は次のようになります。 元のユーザー: User{ name='user', age =22, mark=Mark{chinese=100, math=99}}
クローンユーザー: User{name='user', age=22, mark=Mark{chinese=100, math =99}}
変更された元のユーザー: User{name='user', age=22, mark=Mark{chinese=100, math=60}}
変更されたクローン ユーザー: User{name=' user'、age =22、mark=Mark{chinese=100, math=99}}
import java.io.*; class Mark implements Serializable { private int chinese; private int math; public Mark(int chinese, int math) { this.chinese = chinese; this.math = math; } public void setChinese(int chinese) { this.chinese = chinese; } public void setMath(int math) { this.math = math; } @Override public String toString() { return "Mark{" + "chinese=" + chinese + ", math=" + math + '}'; } } public class User implements Serializable{ private String name; private int age; private Mark mark; public User(String name, int age,Mark mark) { this.name = name; this.age = age; this.mark = mark; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + ", mark=" + mark + '}'; } public static void main(String[] args) throws IOException, ClassNotFoundException { Mark mark = new Mark(100,99); User user = new User("user",22,mark); ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(bo); oo.writeObject(user);//序列化 ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); ObjectInputStream oi = new ObjectInputStream(bi); User userClone = (User) oi.readObject();//反序列化 System.out.println("原user:"+user); System.out.println("克隆的user:"+userClone); user.mark.setMath(59); System.out.println("修改后的原user:"+user); System.out.println("修改后的克隆user:"+userClone); } }出力結果: 元のユーザー: User{name='user', age=22, mark=Mark{chinese= 100, math=99}}
クローンされたユーザー: User{name='user', age=22, mark=Mark{chinese=100, math=99}}
変更された元のユーザー: User{ name ='user', age=22, mark=Mark{chinese=100, math=60}}
変更されたクローン ユーザー: User{name='user', age=22, mark=Mark{chinese= 100, math =99}}
import java.io.*; import java.util.Arrays; public class User implements Serializable{ private String name; private int age; private int[] arr; public User(String name, int age, int[] arr) { this.name = name; this.age = age; this.arr = arr; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + ", arr=" + Arrays.toString(arr) + '}'; } public static void main(String[] args) throws IOException, ClassNotFoundException { int[] arr = {1,2,3,4,5,6}; User user = new User("user",22,arr); ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(bo); oo.writeObject(user);//序列化 ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); ObjectInputStream oi = new ObjectInputStream(bi); User userClone = (User) oi.readObject();//反序列化 System.out.println("原user:"+user); System.out.println("克隆的user:"+userClone); user.arr[1] = 9; System.out.println("修改后的原user:"+user); System.out.println("修改后的克隆user:"+userClone); } }
以上がJava オブジェクトのシャロー クローン作成とディープ クローン作成の詳細な分析 (例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。