clone()
で保護されていると定義されている具体的な理由は何java.lang.Object
ですか?
11 に答える
clone が保護されているという事実は、メソッドがインターフェースclone
で宣言されていないという事実と同様に、非常に疑わしいものです。Cloneable
次のように言うことができないため、データのコピーを取得する方法はほとんど役に立ちません。
if(a instanceof Cloneable) {
copy = ((Cloneable) a).clone();
}
Cloneable
の設計は、現在では大きく誤りと見なされていると思います(以下の引用)。私は通常、インターフェイスの実装を作成できるようにしたいと考えていますCloneable
が、必ずしもインターフェイスを作成する必要はありませんCloneable
(の使用と同様Serializable
)。これはリフレクションなしでは実行できません。
ISomething i = ...
if (i instanceof Cloneable) {
//DAMN! I Need to know about ISomethingImpl! Unless...
copy = (ISomething) i.getClass().getMethod("clone").invoke(i);
}
Josh Bloch の効果的な Javaからの引用:
「Cloneable インターフェースは、オブジェクトがクローン作成を許可することをアドバタイズするための mixin インターフェースとして意図されていました。残念ながら、この目的を果たすことができません...これはインターフェースの非常に非典型的な使用法であり、エミュレートされるものではありません。 ... インターフェイスを実装してクラスに何らかの影響を与えるためには、それとそのすべてのスーパークラスが、かなり複雑で強制力がなく、ほとんど文書化されていないプロトコルに従わなければなりません」
clone
現在のクラスに固有になるようにオーバーライドする必要があるため、保護されています。任意のオブジェクトを複製する public メソッドを作成することは可能clone
ですが、これは、それを必要とするクラス専用に作成されたメソッドほど良くはありません。
Clone メソッドは、オブジェクトに対して直接使用することはできません。そのため、サブクラスによってオーバーライドされることが意図されています。
もちろん、それはパブリックであり、クローンが不可能な場合に適切な例外をスローすることもできますが、それは誤解を招くと思います.
clone が現在実装されている方法を見ると、なぜ clone を使用したいのか、オブジェクトをどのように複製したいのかを考えさせられます。
私見は、これと同じくらい簡単です:
#clone
複製不可能なオブジェクトで呼び出してはならないため、公開されません#clone
Object
適切なクラスの浅いコピーを取得するために Cloneable を実装するサブクラス ob によって呼び出される必要があります
サブクラスからは呼び出せるが、他のクラスからは呼び出せないメソッドの適切なスコープは?
ですprotected
。
もちろん、実装するクラスCloneable
はこのメソッドを公開するため、他のクラスから呼び出すことができます。
はい、私が遭遇したのと同じ問題です。しかし、私はこのコードを実装することでそれを解決します
public class Side implements Cloneable {
public Side clone() {
Side side = null;
try {
side = (Side) super.clone();
} catch (CloneNotSupportedException e) {
System.err.println(e);
}
return side;
}
}
前に誰かが言ったように。
また、Sun の開発者もただの人間であり、クローン メソッドを保護されたものとして実装するという大きな間違いを犯しました。機能しないクローン メソッドを ArrayList に実装したのと同じ間違いです! そのため、一般に、経験豊富な Java プログラマーでさえも、clone メソッドについてはるかに深い誤解が存在します。
しかし、私は最近、オブジェクトがどのように構築され、何が含まれているかに関係なく、オブジェクトをすべてのコンテンツとともにコピーするための迅速かつ簡単なソリューションを見つけました。ここで私の答えを参照してください: Object.clone()
繰り返しになりますが、Java JDK フレームワークは素晴らしい考え方を示しています。
複製可能なインターフェースに「public T clone();」が含まれていない これは、インスタンスのクローンを作成できるようにする属性 (たとえば、Serializable) のように機能するためです。
次の理由により、この設計に問題はありません。
Object.clone() は、カスタム定義のクラスで必要なことを行いません。
Myclass が Cloneable を実装している場合 => clone() を "public MyClass clone()" で上書きします
MyInterface extends Cloneable と MyInterface を実装するいくつかの MyClasses がある場合: 「public MyInterface clone();」を定義するだけです。MyInterface オブジェクトを使用するすべてのメソッドは、MyClass クラスに関係なく、それらを複製できます。