ホームページ  >  記事  >  Java  >  Javaオブジェクトのcloneメソッドを徹底解析

Javaオブジェクトのcloneメソッドを徹底解析

高洛峰
高洛峰オリジナル
2017-01-17 16:52:301350ブラウズ

1 protected ネイティブ オブジェクト clone() throws CloneNotSupportedException;

1. メソッドはネイティブ キーワードによって変更されます

Java のネイティブ キーワードは、このメソッドがネイティブ メソッドであることを示します ([Java ネイティブの説明])。さらに、ネイティブ修飾メソッドの実行効率は、非ネイティブ修飾メソッドの実行効率よりも高くなります。

2. メソッドは protected によって変更されます

クラスが clone() メソッドをオーバーライドする場合、他のすべてのクラスがこのクラスのこのメソッドにアクセスできるようにするために、メソッドを public アクセス修飾子に変更する必要があります。

3. メソッドが CloneNotSupportedException をスローする

clone() メソッドをオーバーライドしたいクラスは、java.lang.Cloneable インターフェース自体を実装する必要があります。実装しない場合は、CloneNotSupportedException がスローされます。

2. clone() の役割

注: ここでのオブジェクトは、特に複合型を指します。

1. シンプル = 操作

Java の複合型オブジェクトは参照型であり、オブジェクトのメモリ アドレスを格納することが多いことがわかっています。したがって、= 演算子のような単純な代入演算だけを使用することはできません。オブジェクト a を別のオブジェクト b に割り当てる場合、オブジェクト a のメモリ アドレスを b に割り当てるだけで、両方のオブジェクトが同じメモリ アドレスを指すようになります。この結果、1 つのオブジェクトに対する変更が他のオブジェクトに影響を与えることになります。以下の図に示すように:

Person p1 = new Person();
Person p2 = p1;

java object 之clone方法全面解析

2. clone()

clone() メソッドを使用すると、オブジェクトのコピーを簡単に作成でき、2 つのオブジェクトは異なるメモリ アドレスを指します。以下の図に示すように:

Person p1 = new Person();
Person p2 = p1.clone();

java object 之clone方法全面解析

3. 浅いクローンと深いクローン 1. 浅いクローン (浅いコピー)

浅いクローンは、クローン オブジェクト内のフィールドではなく、オブジェクト自体のクローンのみを指します。 super.clone() を呼び出すだけで、浅いクローンになります。コピーされたオブジェクトは別のメモリ アドレスを指しますが、オブジェクト内のフィールドは前のオブジェクトと同じメモリ アドレスを指し続けます。

public class ShallowClone implements Cloneable {
 
  public String name;
  public int age;
  public Person person;
 
  public ShallowClone() {
  }
 
  public ShallowClone(String name, int age, Person person) {
    this.name = name;
    this.age = age;
    this.person = person;
  }
 
  @Override
  public ShallowClone clone() {
    ShallowClone c = null;
    try {
      c = (ShallowClone) super.clone();
      return c;
    } catch (CloneNotSupportedException e) {
      e.printStackTrace();
    }
    return c;
  }
 
  public static void main(String[] args) {
    Person p = new Person();
    p.name = "p";
    p.age = 10;
 
    ShallowClone c1 = new ShallowClone("Jim", 18, p);
    System.out.printf("before clone: c1 = %s, c1.person = %s\n", c1, c1.person);
    ShallowClone c2 = c1.clone();
    System.out.printf("after clone: c2 = %s, c2.person = %s\n", c2, c2.person);
  }
}

main() 実行の出力:

before clone: c1 = cre.sample.test.object.ShallowClone@558385e3, c1.person = cre.sample.test.Person@2dcb25f1
after clone: c2 = cre.sample.test.object.ShallowClone@742808b3, c2.person = cre.sample.test.Person@2dcb25f1

浅いコピーの説明、ShallowClone オブジェクトのメモリ アドレスは変更されましたが、オブジェクト内の Person フィールドのメモリ アドレスは変更されていません

2 . ディープ クローン (ディープ コピー)

ディープ クローンとは、オブジェクト自体のクローン作成だけでなく、オブジェクト内のフィールドのクローン作成も指します。

/**
 * deep clone代码示例
 * Created by CreGu on 2016/6/9.
 */
public class DeepClone implements Cloneable {
  public String name;
  public int age;
  public Person person;
 
  public DeepClone() {
  }
 
  public DeepClone(String name, int age, Person person) {
    this.name = name;
    this.age = age;
    this.person = person;
  }
 
  @Override
  public DeepClone clone() {
    DeepClone c = null;
    try {
      c = (DeepClone) super.clone();
      c.person = person.clone();
      return c;
    } catch (CloneNotSupportedException e) {
      e.printStackTrace();
    }
    return c;
  }
 
  public static void main(String[] args) {
    Person p = new Person();
    p.name = "p";
    p.age = 10;
 
    DeepClone c1 = new DeepClone("Jim", 18, p);
    System.out.printf("before clone: c1 = %s, c1.person = %s\n", c1, c1.person);
    DeepClone c2 = c1.clone();
    System.out.printf("after clone: c2 = %s, c2.person = %s\n", c2, c2.person);
  }
}

main() の出力を実行します:

before clone: c1 = cre.sample.test.object.DeepClone@558385e3, c1.person = cre.sample.test.Person@2dcb25f1
after clone: c2 = cre.sample.test.object.DeepClone@742808b3, c2.person = cre.sample.test.Person@70535b58

ディープ コピーの説明では、DeepClone オブジェクトのメモリ アドレスが変更されましたが、オブジェクト内の Person フィールドのメモリ アドレスも変更されました。

上記の Java オブジェクトの clone メソッドの包括的な分析は、エディターによって共有されたすべての内容です。参考になれば幸いです。また、PHP 中国語 Web サイトをサポートしていただければ幸いです。

Java オブジェクトの clone メソッドのより包括的な分析と関連記事については、PHP 中国語 Web サイトに注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。