web-dev-qa-db-ja.com

Javaでclone()メソッドを使用する理由

なぜJavaでclone()メソッドを使用するのですか? (メモリの制約に関して答えを出してください。)それはメモリ使用量を減らしますか?はいの場合、どのように?それはメモリリークの影響を減らしますか?

30
Abhisek

クローンを使用せず、コピーコンストラクタを実装するとは別に、メモリの制約について質問しました。

cloningの考え方は、複製されたオブジェクトの正確な複製を作成することです。したがって、最悪の場合、その後、メモリの2倍の量を使用します。実際には-文字列はしばしばインターンされ、(通常は)複製されないため、少し少なくなります。それはcloneメソッド/コピーコンストラクターの実装者次第ですが。

次に、コピーコンストラクターを持つクラスの短い例を示します。

public class Sheep {
  private String name;
  private Fur fur;
  private Eye[2] eyes;
  //...

  // the copy constructor
  public Sheep(Sheep sheep) {
    // String already has a copy constructor ;)
    this.name = new String(sheep.name);

    // assuming Fur and Eye have copy constructors, necessary for proper cloning
    this.fur = new Fur(sheep.fur); 
    this.eyes = new Eye[2];
    for (int i = 0; i < 2; i++) 
       eyes[i] = new Eye(sheep.eyes[i]);
  }
}

使用法:

Sheep dolly = getDolly();  // some magic to get a sheep
Sheep dollyClone = new Sheep(dolly);
19
Andreas_D

私達はそれを使わないべきです。 壊れた古いイディオム 。これは新しいコードでは避けてください。可能な限り、代わりにコピーコンストラクタを使用することをお勧めします。

14
Péter Török

clone()はオブジェクトの値を別の値にコピーします。 clone()メソッドは、オブジェクトの正確なコピーを作成するための余分な処理タスクを節約します。

以下の例でわかるように、両方の参照変数は同じ値を持っています。

class Student18 implements Cloneable {

    int rollno;
    String name;

    Student18(int rollno, String name) {

        this.rollno = rollno;
        this.name = name;
    }

    public static void main(String args[]) {

        try {
            Student18 s1 = new Student18(101, "amit");

            Student18 s2 = (Student18) s1.clone();

            System.out.println(s1.rollno + " " + s1.name);
            System.out.println(s2.rollno + " " + s2.name);

        } catch (CloneNotSupportedException c) {
        }

    }

    public Object clone() throws CloneNotSupportedException {

        return super.clone();
    }
} 

出力:

101 amit
101 amit

新しいキーワードで別のオブジェクトを作成し、別のオブジェクトの値をこのオブジェクトに割り当てる場合、このオブジェクトで多くの処理が必要になります。したがって、余分な処理タスクを保存するには、clone()メソッドを使用します。

8
Jaimin Patel

同じデータを持つ多くのオブジェクトを使用する必要がある場合は、新しいキーワードを使用してオブジェクトを作成しないでください。 cloneメソッドを使用してオブジェクトを作成します。cloneメソッドを使用してオブジェクトを作成する操作は、新しいキーワードを使用するよりも高速です。

4
Kunal

オブジェクトのコピーを作成することは、最初は簡単な作業のように見えます。

すべてのプロパティの値を同じクラスの別のインスタンスにコピーするだけです。しかし、他のオブジェクトへの参照である変数についてはどうでしょうか?これらの参照値のコピーは、最初のクラスと同じオブジェクトを指すことを意味します。

しかし、多分それは私たちが望むものではありません。おそらく、コピーによって参照されるすべてのオブジェクトも独立したコピーにする必要があります。

これらの2つのタイプのオブジェクトコピーは、次のように呼ばれます。

浅いコピー-元のオブジェクトのすべての属性の正確なビットコピー深いコピー-プリミティブは正確にコピーされますが、参照されたオブジェクトは参照自体ではなくコピーされます。すべてのJavaクラスによって継承されるObjectクラスには、すべてのプロパティの正確なビットコピーを作成するclone()メソッドが含まれています。

ただし、clone()は保護されたメソッドです。したがって、特定のオブジェクトは、パッケージの外部にあるクラスのインスタンスによって複製することはできません(それらがそのオブジェクトのクラスのサブクラスでない限り)。これにより、クラス設計者は、作成するクローン(浅いまたは深い)の種類を明示的に指定できます。

Javaでは、クローン可能なインターフェースを実装するために、clone()メソッドをオーバーライドするクラスが必要です。アクセス制限をオーバーライドするには、clone()メソッドも公開する必要があります。

たとえば、HashTableクラスは複製可能を実装します。そのclone()メソッドは浅いコピーを作成するため、コピーされたHashTableのキーと値は元のオブジェクトと同じオブジェクトを参照します。

多くのコアJavaクラスは、ただし、クローン可能を実装していません。そのようなクラスに対してclone()メソッドが呼び出されると、CloneNotSupportedExceptionが発生します。

3
Noor Khan

参照 クローン制約

簡単に言えば、参照の代わりにオブジェクトをコピーするために使用され、メモリ使用量が増加します。

0
Kevin

Clone()の使用は避けてください ここ は良い例です

0
Abhilash