Javaの深浅コピー

3095 ワード

Javaの深浅コピー
基本タイプ:コピーデータの値その他タイプ:コピーアドレスの参照、コピーされた新しいオブジェクトは元のオブジェクトとインスタンス変数を共有し、アクセス権の影響を受けないStringタイプ:コピーされたものも参照ですが、その内容は文字列プールに格納され、変更時に新しい文字列に再生成され、元の文字列の内容は変わらない(Stringは可変ではありません)基本タイプと同等です.
浅いコピー
浅いコピーは、コピー参照でも「=」を使用して基本タイプに直接値を割り当てることです.
List srcList = new ArrayList<>();
srcList.add("android");
List cpyList = srcList;
srcList.add("ios");

出力の2つのlist,srcList,cpyListにはandroid,iosの2つがある.
深いコピー
深度コピーとは、すべてのアトリビュートを別のオブジェクトにコピーし、いずれかのオブジェクトのいずれかのアトリビュートが変化した場合、他のオブジェクトは影響を受けません.
List srcList = new ArrayList<>();
srcList.add("android");
List cpyList = new ArrayList<>(srcList);
srcList.add("ios");

この2つのlistを出力し、srcListにはandroid、iosの2つがあり、cpyListにはandroidの1つしかありません.
クローンメソッドによるコピー
各オブジェクトはObjectクラスに継承されています.Objectクラスはcloneメソッドを提供しています.Cloneableインタフェースを実装することでコピーの能力を持つことができます.コピーの操作はメモリで行われているので、直接オブジェクトを構築するよりもパフォーマンスが速くなります.
public class Student implements Cloneable {
    private String name;
    private Teacher teacher;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    @Override
    protected Student clone() {
        Student s = null;
        try {
            s = (Student) super.clone();
            s.setTeacher(s.getTeacher());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return s;
    }

    public static void main(String[] args) {
        Student s1 = new Student();
        s1.setName("Yao");
        s1.setTeacher(new Teacher("Kobe"));
        Student s2 = s1.clone();
        s2.setName("Yi");
        s2.getTeacher().setName("Jordan");
        System.out.println(s1.getName() + "'s teacher is "
                + s1.getTeacher().getName());
        System.out.println(s2.getName() + "'s teacher is "
                + s2.getTeacher().getName());

    }
}

class Teacher {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Teacher(String name) {
        super();
        this.name = name;
    }
}


出力:Yao's teacher is Jordan Yi's teacher is Jordanここでteacherに関するコピーは「=」番号で操作され、浅いコピーのみが実現されます.
@Override
protected Student clone() {
    Student s = null;
    try {
        s = (Student) super.clone();
        s.setTeacher(new Teacher(s.getTeacher().getName()));
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
    return s;
}

Studioクラスのcloneメソッドをこのように変更すると、深いコピーが実現されます.出力:Yao's teacher is Kobe Yi's teacher is Jordan
オブジェクトのシーケンス化により、writeObjectとreadObjectを使用してオブジェクトの深いコピーを実現することもできます.