8
public class Student implements Cloneable {
    public Student clone() {
        Student clonedStudent = (Student) super.clone();
        return clonedStudent;
    }
}

Java がオブジェクト クラス オブジェクトを返すのではなく、学生オブジェクトを返すのはなぜですか。スーパーを使用しているため。Java自体がクローンメソッドで浅いクローンを提供するということですか?

4

4 に答える 4

0

java.lang.Objectclone()Java でのメソッドのデフォルト実装を提供します。Objectクラスで保護およびネイティブとして宣言されているため、ネイティブ コードで実装されます。clone()メソッドを呼び出してオブジェクトを返すという慣習があるためsuper.clone()、クローン作成プロセスは最終的にjava.lang.Object clone()メソッドに到達します。Cloneableこのメソッドは、まず、対応するオブジェクトがマーカー インターフェイスであるインターフェイスを実装しているかどうかを確認します。そのインスタンスが Cloneable を実装していない場合はCloneNotSupportedException、オブジェクトのクローン作成中に常に処理する必要があるチェック済み例外である Java をスローします。Java では、クラスがクローン作成をサポートする必要がある場合、次のことを行う必要があります。

A) インターフェイスを実装する必要がありCloneableます。B)クラスclone()からメソッドをオーバーライドする必要があります。Object[それは奇妙だ。clone()メソッドはインターフェースにあるはずCloneableです。]

メソッドに関する Java ドキュメントをclone()以下に示します (フォーマット済みおよび抜粋)。/* このオブジェクトのコピーを作成して返します。「コピー」の正確な意味は、オブジェクトのクラスによって異なります。一般的な意図は、任意のオブジェクトxについて、式: 1)x.clone() != xが true になり、//複製されたオブジェクトに別のメモリ アドレスが割り当てられることを保証することです。2)x.clone().getClass() == x.getClass()は true になりますが、これらは絶対的な要件ではありません。//元のオブジェクトと複製されたオブジェクトは同じクラス型を持つ必要がありますが、必須ではありません。3)x.clone().equals(x)真になります。これは絶対的な要件ではありません。//元のオブジェクトと複製されたオブジェクトはequals()メソッドを使用して等しくなければなりませんが、必須ではありません。*/

例を見てみましょう:

public class MyClone {
    int x;
    public static void main(String[] args) throws
       CloneNotSupportedException {
        MyClone c = new MyClone();
        MyClone a = (MyClone) c.clone();  // Type-cast is required
    }
}

はクラスclone()の一部であり、インターフェースを実装しないため、独自のクラスがインターフェースを実装しない場合、JVM はこのクラスがクローン作成に適していることを認識しないため、出力されます。ObjectObjectCloneableCloneableCloneNotSupportedException

と言うとき、可能なことは 2 つだけですMyClone a = (MyClone) c.clone();

どちらかが複製されたオブジェクトを返します。

または、スローしCloneNotSupportedExceptionます。

オブジェクトのクローンを作成するときにクラスに実装することが必須ではないことは明らかであるためclone()、そうしない場合、クラスのclone()メソッドObjectは保護されていると宣言されます — 同じパッケージのサブクラスとメンバーのみが呼び出すことができclone()ますオブジェクト。それを変更したい場合は、オーバーライドして公開する必要があります。

clone()メソッド呼び出し前のチェック:

if(c instanceof Cloneable) {
    MyClone a = (MyClone) c.clone();
}

注: gets が呼び出されたときに、コンストラクターは呼び出されませんclone()。そのクラスのすべてのメンバー変数を適切に設定するのは私たちの責任です。

実装:

Room.java
public class Room {
 private String roomSize;
 public Room(String roomSize){
  this.roomSize = roomSize;
}
 //Any Getters-Setters go here
}
Flat.java
public class Flat implements Cloneable {
 private String flatNumber;
 private Room room;
 public Flat(String size,Room room){
   this.size = size;
   this.room = room;
 }
 public Object clone() {
  try {
   return (Flat)super.clone();
 }
  catch (CloneNotSupportedException e) {
   System.out.println("CloneNotSupportedException comes out : "
   +e.getMessage());
  }
 }
//Any Getters-Setters go here
}
Main.java
public class Main {
  public static void main(String[] args) {
   Room room = new Room("40 X 40");
   Flat flat1 = new Flat(403 , room);
   Flat flat2 = (Flat)flat1.clone();
  }
}

ここsuper.clone()は内部で呼び出されていclone()ます。ご存じのとおり、clone()は で宣言されObjectているため、すべての Java オブジェクトに継承されます。呼び出しsuper.clone()により、スーパークラスのフィールドがコピーされ、フィールドのビットごとのコピーが作成されます。これは浅いコピーとして知られています。つまり、をFlat使用してコピーするclone()と、フィールドflatNumberはそれぞれの値でコピーされますが、部屋は参照によってコピーされます — ビットごとにメモリアドレスがコピーされます。

元のオブジェクトの部屋に加えた変更は、複製されたオブジェクトに反映され、その逆も同様です。これを解決するには、ディープコピーが必要です。ここで、クラスを変更し、インターフェイスとメソッドをRoom実装してから、オブジェクトのメソッド内でオブジェクトのメソッドを呼び出す必要があります。Cloneableclone()clone()Roomclone()Flat

新しい実装

Room.java
public class Room {
    private String roomSize;
    public Room(String roomSize){
       this.roomSize = roomSize;
   }
    public Object clone() {
       try {
         return (Room)super.clone();
     }
      catch (CloneNotSupportedException e) {
       System.out.println("CloneNotSupportedException comes out : "
    +e.getMessage());
     }
   }
   //Any Getters-Setters go here
}
Flat.java
public class Flat implements Cloneable {
    private String flatNumber;
 private Room room;
 public Flat(String size,Room room){
   this.size = size;
   this.room = room;
 }
    public Object clone() {
      Flat flat = null;
      try {
         flat = (Flat)super.clone();
     }
      catch (CloneNotSupportedException e) {
          System.out.println("CloneNotSupportedException comes out : "
    +e.getMessage());
     }
     flat.room = (Room) room.clone();
         return flat;
   }
    //Any Getters-Setters go here
}
Main.java
public class Main {
    public static void main(String[] args) {
       Room room = new Room("40 X 40");
       Flat flat1 = new Flat(403, room);
       Flat flat2 = (Flat)flat1.clone();
   }
}

これにより、クローン作成とその実装についての理解が深まることを願っています。

http://interviewguess.blogspot.in/2017/02/how-does-clone-method-work.htmlに感謝します

于 2017-02-10T13:53:13.110 に答える