9

インターフェースの Java 仕様は、java.lang.Cloneableインターフェースを拡張するすべてのオブジェクトが、clone()内で休眠状態にあるメソッドも実装していることを示すものとして定義していますjava.lang.Object。具体的には、次のように述べています。

クラスは、そのメソッドがそのクラスのインスタンスのフィールドごとのコピーを作成することが正当であることをメソッドCloneableに示すインターフェイスを実装します。java.lang.Object#clone()

私にとって、これは、拡張するすべてのクラスがその中にメソッドCloneableも持っていると想定する必要があることを意味します。public Object clone()これにより、次の方法が有効であると簡単に推測できます。

public static makeACloneFrom(Cloneable c)
{
  return c.clone();
}

ただし、Cloneableソースコード全体 (sans javadoc) は単に

package java.lang;

public interface Cloneable {
}

つまり、それCloneable#clone()は存在しません (そして、上記のサンプル メソッドをコンパイルしようとすると、" " のようなコンパイル時エラーがスローされますcannot find symbol: method clone())。のソース コードにCloneableは、 の影響を受ける何かが含まれているべきではありませんpublic Cloneable clone();か?

Cloneableを実装するクラスがメソッドを持っていると想定できないのはなぜpublic Cloneable clone()ですか?

4

2 に答える 2

7

うーん。 壊れていて、ひどく設計されているので、新しいコードで使用しないでくださいcloneCloneable(効果的なJava項目11を参照してください。)

この特定の理由は、実装するという単なる行為が反射を伴う動作を変更するCloneableような、混乱を招くように実装された魔法のインターフェースであるためです。効果的なJavaによると:CloneableObject.clone

...クラスが実装する場合CloneableObject'scloneメソッドはオブジェクトのフィールドごとのコピーを返します。それ以外の場合は、CloneNotSupportedExceptionをスローします。これは非常に非典型的なインターフェースの使用であり、エミュレートされるものではありません...

于 2012-04-02T18:33:05.507 に答える
7

インターフェースの設計が悪いからです。

効果的な Javaから(申し訳ありませんが、Google ブックスには第 2 版のプレビューがありません):

項目 11:clone慎重にオーバーライドする

このインターフェースは、オブジェクトが複製を許可することをアドバタイズするためのmixin インターフェースCloneable(項目 18)として意図されていました。残念ながら、それはこの目的を果たせません。その主な欠点は、 メソッドがなく、のメソッドが保護されていることです。リフレクション(項目 53) に頼って 、単に を実装しているという理由だけでオブジェクトのメソッドを呼び出すことはできません。オブジェクトにアクセス可能なメソッドがあるという保証がないため、リフレクティブ呼び出しでさえ失敗する可能性があります。cloneObjectclonecloneCloneableclone

于 2012-04-02T18:31:31.890 に答える