Javaで浅いコピーと深いコピーを実装する方法

この記事では、Javaでの浅いコピーと深いコピーの詳細で包括的な知識を例とともに提供します。

クローン作成は、レプリカまたはコピーを作成するプロセスです。 オブジェクト、クローンメソッドJava.lang.Objectは、オブジェクトのコピーまたはレプリカを作成するために使用されます。 Cloneableインターフェースを実装するJavaオブジェクトは、cloneメソッドを使用する資格があります。この記事では、浅いコピーと深いコピーについて次の順序で説明します。

Javaオブジェクトのコピーの作成

次の方法でJavaオブジェクトのレプリカまたはコピーを作成できます。



1.別のメモリ位置にオブジェクトのコピーを作成します。これはディープコピーと呼ばれます。

2.同じメモリ位置を指す新しい参照を作成します。これは、浅いコピーとも呼ばれます。

浅いコピー

cloneメソッドのデフォルトの実装では、ソースオブジェクトの浅いコピーが作成されます。つまり、Objectタイプの新しいインスタンスが作成され、すべてのフィールドが新しいインスタンスにコピーされ、「Object」タイプの新しいオブジェクトが返されます。このオブジェクトは、ソースオブジェクトのオブジェクトタイプで明示的にタイプキャストする必要があります。

オブジェクトの配列java

このオブジェクトには、プリミティブ型とオブジェクト参照を含むソースオブジェクトのすべてのフィールドの正確なコピーがあります。ソースオブジェクトのフィールドに他のオブジェクトへの参照が含まれている場合、新しいインスタンスではそれらのオブジェクトへの参照のみが含まれ、それらのオブジェクトのコピーは作成されません。つまり、浅いコピーに変更を加えると、変更はソースオブジェクトに反映されます。両方のインスタンスは独立していません。

Objectクラスのcloneメソッドは本質的に保護されているため、すべてのクラスがclone()メソッドを使用できるわけではありません。 Cloneableインターフェースを実装し、cloneメソッドをオーバーライドする必要があります。 Cloneableインターフェースが実装されていない場合は、CloneNotSupportedException.super.clone()が取得され、Objectクラスの実装に従って浅いコピーが返されます。

浅いコピーのコード

パッケージcom.testクラスDepartment {文字列empId文字列グレード文字列指定publicDepartment(String empId、文字列グレード、文字列指定){this.empId = empId this.grade =グレードthis.designation =指定}}クラス従業員はCloneableを実装します{intid文字列名Departmentdept public Employee(int id、String name、Department dept){this.id = id this.name = name this.dept = dept} // clone()メソッドのデフォルトバージョン。オブジェクトの浅いコピーを作成します。 protected Object clone()throws CloneNotSupportedException {return super.clone()}} public class ShallowCopyInJava {public static void main(String [] args){Department dept1 = new Department( '1'、 'A'、 'AVP')Employee emp1 = new Employee(111、 'John'、dept1)Employee emp2 = null tr​​y {// emp1のクローンを作成し、それをemp2に割り当てますemp2 =(Employee)emp1.clone()} catch(CloneNotSupportedException e){e。 printStackTrace()} // 'emp1'の指定を出力しますSystem.out.println(emp1.dept.designation)//出力:AVP // 'emp2'の指定を変更しますemp2.​​dept.designation = 'Director' //この変更は、元の従業員 'emp1' System.out.println(emp1.dept.designation)//出力:Director}}に反映されます。

出力:

Output-Shallow-Copy

上記の例では、3つのクラス変数id(int)、name(String)、department(Department)を持つEmployeeクラスemp1があります。

ここで、emp1をemp2に複製して浅いコピーを作成しました。その後、emp2オブジェクトを使用して指定を変更し、同じ変更がemp1にも反映されることを確認しました。


ディープコピー

オブジェクトのディープコピーには、シャローコピーのようにソースオブジェクトのすべてのフィールドの正確なコピーがありますが、ソースオブジェクトがフィールドとしてオブジェクトへの参照を持っている場合のサローコピーとは異なり、オブジェクトのレプリカはクローンを呼び出すことによって作成されます方法。これは、ソースオブジェクトと宛先オブジェクトの両方が互いに独立していることを意味します。複製されたオブジェクトに加えられた変更は、ソースオブジェクトに影響を与えません。

ディープコピーのコード

パッケージcom.testクラス部門はCloneableを実装します{文字列empId文字列グレード文字列指定publicDepartment(文字列empId、文字列グレード、文字列指定){this.empId = empId this.grade = grade this.designation =指定} //クローンのデフォルトバージョン() 方法。保護されたオブジェクトclone()throws CloneNotSupportedException {return super.clone()}}クラスEmployeeはCloneableを実装します{int id String name Department dept public Employee(int id、String name、Department dept){this.id = id this.name = name this.dept = dept} //オブジェクトのディープコピーを作成するためにclone()メソッドをオーバーライドします。 protected Object clone()throws CloneNotSupportedException {Employee emp =(Employee)super.clone()emp.dept =(Department)dept.clone()return emp}} public class DeepCopyInJava {public static void main(String [] args){ Department dept1 = new Department( '1'、 'A'、 'AVP')Employee emp1 = new Employee(111、 'John'、dept1)Employee emp2 = null tr​​y {// emp1のクローンを作成し、それをemp2に割り当てますemp2 =(Employee)emp1.clone()} catch(CloneNotSupportedException e){e.printStackTrace()} // 'emp1'の指定を出力しますSystem.out.println(emp1.dept.designation)//出力:AVP / / 'emp2'の指定の変更emp2.​​dept.designation = 'Director' //この変更は元の従業員 'emp1'に反映されますSystem.out.println(emp1.dept.designation)//出力:AVP}}

出力:

上記のディープコピーの例では、シャローコピーとは異なり、ソースオブジェクトと宛先オブジェクトの両方が互いに独立しています。 emp2で行われた変更は、emp1には影響しません。

浅いコピーと深いコピーの違い

浅いコピー ディープコピー
クローンオブジェクトとソースオブジェクトが完全に分離されていない複製されたオブジェクトとソースオブジェクトは、互いに完全に独立しています。
複製されたインスタンスで行われた変更は、ソースオブジェクトの参照変数に影響を与えます複製されたインスタンスで行われた変更は、ソースオブジェクトの参照変数に影響を与えません。
クローンのデフォルトバージョンはシャローコピーですディープコピーを作成するには、Objectクラスのcloneメソッドをオーバーライドする必要があります。
オブジェクトのクラス変数がフィールドとしてのプリミティブ型のみである場合は、浅いコピーが推奨されますオブジェクトのクラス変数にフィールドとして他のオブジェクトへの参照がある場合は、ディープコピーが推奨されます。
比較的速いです比較的遅いです。

これで、ShallowCopyとDeepCopyの記事は終わりです。両者のさまざまな違いをご理解いただければ幸いです。

チェックしてください 25万人以上の満足した学習者のネットワークを持つ信頼できるオンライン学習会社であるEdurekaが世界中に広がっています。 EdurekaのJavaJ2EEおよびSOAトレーニングおよび認定コースは、Java開発者になりたい学生および専門家向けに設計されています。

質問がありますか?この「浅いコピーと深いコピー」ブログのコメントセクションでそれについて言及してください。できるだけ早くご連絡いたします。