質問:
package GoodQuestions;
public class MyClass {
MyClass() throws CloneNotSupportedException {
try {
throw new CloneNotSupportedException();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
MyClass obj = new MyClass();
MyClass obj3 = (MyClass)obj.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
ここで、クラス「MyClass」は、「Object」クラスのcloneメソッドを呼び出すことにより、独自のオブジェクトを複製できます。同じパッケージ「GoodQuestions」内の別のクラス(「TestSingleTon」)にこのクラス(「MyClass」)のクローンを作成しようとすると、次のコンパイル時エラーがスローされます。
'タイプObjectのclone()メソッドは表示されません'
では、上記のエラーをスローするコードは次のようになりますか?
package GoodQuestions;
public class TestSingleTon {
public static void main(String[] args) {
MyClass obj = new MyClass();
MyClass obj3 = obj.clone(); ---> here is the compile error.
}
}
このエラーは、Objectクラスのclone()メソッドが保護されているために発生します。そのため、それぞれのクラスでclone()メソッドをオーバーライドする必要があります。例えば。 MyClassに以下のコードを追加します
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
Cloneableインターフェイスも実装します。例えば。 public class MyClass implements Cloneable
clone()
はアクセスを保護しています。これをMyClass
に追加します
public Object clone(){
try{
return super.clone();
}catch(Exception e){
return null;
}
}
また、public class MyClass implements Cloneable
に変更します
Clone()は保護されたメソッドだからです。詳細については、 Object.clone() を参照してください。
MyClassのclone()をオーバーライドし、クラスに Cloneable インターフェイスを実装させます。
微妙な点は、MyClass
のclone()
メソッドが継承され、MyClass
で定義されていないことです。したがって、MyClass
はオブジェクトのclone()
を呼び出すことができます。これは、保護ですが、MyClass
は実際にはhaveではないからですclone()
自体、したがってTestSingleTon
はclone()
メソッドがないため、MyClass
のclone()
にアクセスできません。両方とも同じパッケージ内にありますが、clone()
を本当に「持っている」ことを保証するために、MyClass
でclone()
メソッドを定義する必要があります。ところで、Cloneable
にMyClass
インターフェースを実装することを忘れないでください。
クラスにCloneableインターフェースを実装させるだけです。 clone()の実装を提供する必要はありません。
Object.clone()
メソッドはアクセスを保護しています。つまり、it's visible to sub-classes and classes in the same package
。
オブジェクトを手動でコピーするには、copy constructorを用意しておくとよいでしょう。
/**
Deep copy all the information from other to this
*/
public MyClass (MyClass other) {
this.id = other.id;
}
私はこれについていくつかのテストコードを実行しました。
保護されたメンバーがパッケージ全体で継承されると、継承されたクラスのプライベートメンバーになります
一方、
保護されたメンバーが同じパッケージ内で継承されると、デフォルト継承されたクラスのメンバーになります。
この例では、Objectクラスのclone()はパッケージ全体でMyClassに継承されます。オブジェクトクラスはJava.langパッケージにあり、MyClassはGoodQuestionsパッケージにあります。そのため、clone()メソッドはMyClassクラスのプライベートメンバーになります。
TestSingleTonクラスからclone()メソッドにアクセスできない理由を説明しています。
MyClassのクローンを作成するには、Cloneableインターフェイスを実装する必要があります