Java clone–deepおよびshallow copy–copyコンストラクタ

クローンは、元のコピーの正確なコピーです。 Javaでは、本質的に、元のオブジェクトと同様の状態のオブジェクトを作成する機能を意味します。 Javaclone()メソッドはこの機能を提供します。

この記事では、Javaクローンの重要な側面のほとんどを探求します。P>

Table of Contents1. What is clone?2. Java Cloneable interface and clone() method3. Shallow Copy4. Deep Copy5. Java Copy Constructors6. Deep copy with serialization7. Cloning using Apache commons8. Java clone best practices

Javaクローンとは何ですか?したがって、複製は元のオブジェクトのコピーを作成することです。 その辞書の意味は次のとおりです : “の同一コピーを作成します。つまり、オブジェクトクラスはclone()メソッドが呼び出されるクラスの構造について考えていないためです。

したがって、JVMがクローン作成のために呼び出されたときは、次のことを行います。

  1. クラスにプリミティブデータ型メンバーのみがある場合、オブジェク
  2. クラスに任意のクラス型のメンバーが含まれている場合、それらのメンバーへのオブジェクト参照のみがコピーされるため、元のオブジェクトとクロー

上記のデフォルトの動作とは別に、この動作を常にオーバーライドして独自の動作を指定することができます。 これは、オーバーライドを使用して行われますclone()メソッド。 それがどのように行われるか見てみましょう。

Java Cloneableインターフェイスとclone()メソッド

オブジェクトの複製をサポートするすべての言語には独自のルールがあり、javaもそうです。 Javaでは、クラスがクローニングをサポートする必要がある場合は、次のことを行う必要があります。

  1. Cloneableインターフェイスを実装する必
  2. オブジェクトクラスからclone()メソッドをオーバーライドする必要があります。

続きを読む:Cloneableインターフェイスは、javaで壊れています

clone()メソッドについてのJavaドキュメントは、以下

  1. 最初の文は、複製されたオブジェクトが別々のメモリアドレス割り当てを持つことを保証します。
  2. 第二の文は、元のオブジェクトと複製されたオブジェクトが同じクラス型を持つべきであることを示唆しているが、それは必須ではありません。
  3. 第三の文は、元と複製されたオブジェクトがequals()メソッドを使用して等しくなければならないことを示唆していますが、必須ではありません。

例を使ってJava cloneを理解しましょう。 私たちの最初のクラスは、3つの属性を持つEmployeeidnamedepartmentidname。したがって、Employeeクラスを複製する必要がある場合は、次のようにする必要があります。素晴らしい、私たちは正常にEmployeeオブジェクトをクローン化しました。 しかし、同じオブジェクトへの2つの参照があり、両方ともアプリケーションのさまざまな部分でオブジェクトの状態を変更することに注意してく どのように見たいですか? どれどれどれどれどれどれどれどれどれどれどれ

おっと、複製されたオブジェクトの変更は元のものにも表示されます。 このようにして、複製されたオブジェクトは、許可されている場合にシステム内で大混乱を引き起こす可能性があります。 誰もが来て、あなたのアプリケーションオブジェクトを複製し、彼が好きなことを行うことができます。 これを防ぐことはできますか??答えはイエスです、私たちはできます。

答えはイエスです。

これを防ぐには、Javaディープコピーを作成し、コピーコンストラクタを使用します。 私たちはこの記事の後半でそれらについて学びます。 最初に、Javaのdeep cloningとshallow cloningが何であるかを見てみましょう。

Javaの浅いコピー

浅いクローンは、Javaでは”デフォルトの実装”です。 オーバーライドされたcloneメソッドでは、すべてのオブジェクトタイプ(プリミティブではない)を複製していない場合、浅いコピーを作成してい

上記の例はすべて、DepartmentEmployeecloneメソッ さて、私たちは深いクローニングが表示されます次のセクションに移動します。

Java Deep Copy

Deep cloneは、ほとんどの場合、望ましい動作です。 ディープコピーでは、元のオブジェクトとは独立したクローンを作成し、複製されたオブジェクトに変更を加えても元のオブジェクトには影響しません。Javaでどのようにディープコピーが作成されるかを見てみましょう。私はEmployeeclone()cloneDepartmentクラスに追加しました。

今、私たちのクローニングコードをテストすると、所望の結果を与え、部門の名前は変更されません。

ここで、複製されたオブジェクトの状態を変更しても、元のオブジェクトには影響しません。

深いクローンを作成するには、次のルールを満たす必要があります–

  • プリミティブを別々にコピーする必要はありません。
  • 元のクラスのすべてのメンバークラスはクローニングをサポートする必要があり、コンテキスト内の元のクラスのクローンメソッドでsuper.clone()すべてのメンバークラスで呼び出す必要があります。
  • いずれかのメンバークラスがクローン作成をサポートしていない場合、cloneメソッドでは、そのメンバークラスの新しいインスタンスを作成し、そのすべての属性を新しいメンバークラスオブジェクトに1つずつコピーする必要があります。 この新しいメンバークラスオブジェクトは、複製されたオブジェクトに設定されます。

続きを読む:インメモリ直列化を使用した深いクローニング

Javaコピーコンストラクタ

コピーコンストラクタは、独自のクラ したがって、classのインスタンスをcopy constructorに渡すと、constructorは引数インスタンスからコピーされた値を持つclassの新しいインスタンスを返します。 それはあなたがCloneableインターフェイスでオブジェクトを複製するのに役立ちます。

例でこれを見てみましょう:

public class PointOne {private Integer x;private Integer y;public PointOne(PointOne point){this.x = point.x;this.y = point.y;}}

このメソッドは単純に見え、継承が来るまでです。 上記のクラスを拡張してクラスを定義するときは、そこにも同様のコンストラクタを定義する必要があります。 子クラスでは、子固有の属性をコピーし、引数をスーパークラスのコンストラクタに渡す必要があります。 どのように見てみましょうか?

だから、私たちは今大丈夫ですか?

PointTwoPointOnePointOnePointTwoのインスタンスを引数として渡します。 これをコードで見ることができます:

コピーコンストラクタを作成する別の方法は、静的ファクトリメソッドを持つことです。 彼らは引数でクラス型を取り、クラスの別のコンストラクタを使用して新しいインスタンスを作成します。 次に、これらのファクトリメソッドは、前のステップで作成された新しいクラスインスタンスにすべての状態データをコピーし、この更新されたイン

シリアル化を使用したJavaディープコピー

シリアル化は、ディープクローニングのもう一つの簡単な方法です。 このメソッドでは、複製するオブジェクトをシリアル化し、シリアル化を解除するだけです。 明らかに、複製する必要があるオブジェクトはSerializableインターフェイスを実装する必要があります。さらに進む前に、この手法は軽く使用しないように注意する必要があります。

  1. まず第一に、シリアル化は非常に高価です。 これは、clone()SerializableSerializableはトリッキーであり、すべてのクラスがそれを正しく得るために頼ることができるわけではありません。

続きを読む:Javaでシリアル化を実装するためのガイド

Java clone–SerializationUtils

Apache commonsでは、SerializationUtilsクラスには、深いクローニングのためのユーティリティ機能もあります。 あなたが興味を持っていると感じたら、彼らの公式文書に従ってください。

<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.7</version></dependency>
SomeObject cloned = org.apache.commons.lang.SerializationUtils.clone(someObject);

Java clone best practices

  1. 特定のクラスのclone()メソッドを呼び出すことができるかどうかわからないときは、そのクラスに実装されているかどうかわからないため、クラスがclone()メソッドを呼び出すことができるかどうかを確認することができます。Cloneable
    if(obj1 instanceof Cloneable){ obj2 = obj1.clone();}//Dont do this. Cloneable dont have any methodsobj2 = (Cloneable)obj1.clone();
  2. 複製されるオブジェクトでコンストラクタが呼び出されません。 その結果、すべてのメンバーが適切に設定されていることを確認するのはあなたの責任です。 また、コンストラクタの呼び出しをカウントしてシステム内のオブジェクトの数を追跡している場合は、カウンタを増やすための新しい追加の場私はこの投稿があなたのための復習であり、Java8cloneメソッドとそれが正しい使用法についてのより多くの情報を得るのを助けることを願っていま また、Java cloneのインタビューの質問に返信するのにも役立ちます。

    幸せな学習!

    幸せな学習!!

    この投稿は役に立ちましたか?

    あなたが投稿を好きなら私たちに知らせてください。 それが私たちが改善できる唯一の方法です。
    はい
    いいえ

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です