clone メソッドと Cloneable インターフェイス - 1

「こんにちは、アミーゴ!」

「こんにちは、キム。」

「clone() メソッドについて説明します。」

「このメソッドのポイントは、オブジェクトのクローンを作成すること、つまりオブジェクトのクローン/コピー/複製を作成することです。」

「このメソッドが呼び出されると、Java 仮想マシンは呼び出されたオブジェクトの複製を作成して返します。

Object クラスの clone メソッドの実装は非常に原始的です。新しいオブジェクトが 1 つだけ作成され、元のオブジェクトのフィールドの値がそのフィールドに割り当てられます。

コピーされたオブジェクトに他のオブジェクトへの参照が含まれている場合、それらの参照もコピーされます。これらのオブジェクトの複製は作成されません。」

「うーん。これ以上続けることはあまりありません。」

「実際のところ、Java 仮想マシンはどのオブジェクトを複製できるか、どのオブジェクトを複製できないかがわかりません。たとえば、ファイルは複製できません。同じことが System.in ストリームにも当てはまります。」

「それで、本格的なクローン作成の問題がクラスの開発者に投げかけられました。」 これはすべて、equals メソッドの処理方法と似ています。hashCode に相当するものとして、Cloneable インターフェイスもあります。」

Cloneableインターフェイスは、いわゆる「マーカー インターフェイス」です。これにはメソッドはなく、特定のクラスをマークするために使用されます。

「クラスの開発者が、そのクラスのオブジェクトを複製できると信じる場合、そのクラスにこのインターフェイスをマークします (つまり、クラスに Cloneable を実装させます)。」

「開発者がクローン メソッドの標準実装を気に入らない場合は、正しい方法で複製オブジェクトを作成する独自の実装を作成する必要があります。」

「 clone () メソッドを呼び出すと、Java はオブジェクトが Cloneable インターフェースをサポートしているかどうかをチェックします。サポートしている場合は、 clone ()メソッドを使用してオブジェクトのクローンを作成します。サポートしていない場合は、CloneNotSupportedException をスローします。」

「つまり、clone メソッドをオーバーライドするか、クラスに Cloneable を実装させる必要があるということですか?」

「はい、ただしメソッドをオーバーライドする必要があります。 clone() メソッドは保護されたものとして宣言されているため、そのパッケージ (java.lang.*) 内のクラスまたはそのサブクラスによってのみ呼び出すことができます。」

「少し混乱しています。では、オブジェクトのクローンを作成するには何をする必要がありますか?」

「オブジェクト クラスの «default» クローン作成メソッドを使用したい場合は、次のことを行う必要があります。

a) Cloneable インターフェースをクラスに追加します。」

" b) clone メソッドをオーバーライドし、実装内でスーパークラスの実装を呼び出します。"

class Point implements Cloneable
{
 int x;
 int y;

 public Object clone()
 {
  return super.clone();
 }
    }

「あるいは、clone メソッドの実装を完全に自分で書くこともできます。」

class Point
{
 int x;
 int y;

 public Object clone()
 {
  Point point = new Point();
  point.x = this.x;
  point.y = this.y;
  return point;
 }
}

「面白い方法ですね。ぜひ使ってみます。たまには…」