web-dev-qa-db-ja.com

Cloneableが非推奨ではないのはなぜですか?

JavaのCloneableインターフェイスが壊れていることは一般的に理解されています。これには多くの理由がありますが、私は言及しません。 others はすでにやっていました。また、 Javaアーキテクト 自身の位置でもあります。

したがって、私の質問は次のとおりです。なぜ非推奨になっていないのですか?コアJavaチームが破損していると判断した場合は、非推奨と見なされている必要があります。そうすることに対する彼らの理由は何ですか(Java 8では 非推奨ではありません )?

137
Kao

「なぜCloneableは非推奨ではないのか?」 (実際、XXで非推奨にならないのは、非推奨に注意が払われていないからです。

最近廃止されたもののほとんどは、それらを削除する特定の計画があるため、廃止されました。たとえば、 LogManageraddPropertyChangeListenerおよびremovePropertyChangeListenerメソッドは Java SE 8 で非推奨Java SE 9でそれらを削除する意図。(理由は、それらがモジュールの相互依存関係を不必要に複雑にするためです。)実際、これらのAPIはすでに 初期のJDK 9から削除されました 開発ビルド(同様のプロパティ変更リスナー呼び出しも_Pack200_から削除されたことに注意してください; JDK-8029806 を参照してください。)

CloneableおよびObject.clone()に対して同様の計画は存在しません。

より長い答えには、これらのAPIに何が起こると予想されるか、廃止された場合にプラットフォームにどのようなコストまたは利益が生じるか、APIが廃止されたときに開発者に伝えられることなど、さらに質問を議論することが含まれます。私は最近のJavaOneの講演でこのトピックを調べました Debt and Deprecation 。 (そのリンクでスライドを利用できます。 ビデオはこちら 。)JDK自体は非推奨の使用法に関してあまり一貫性がなかったことがわかります。たとえば、次のようないくつかの異なることを意味するために使用されています。

  • これは危険であり、使用するリスクに注意する必要があります(例:Thread.stop()Thread.resume()、およびThread.suspend())。

  • これは将来のリリースで削除される予定です

  • これは廃止されており、異なるものを使用することをお勧めします(例:_Java.util.Date_のメソッドの多く)

これらはすべて別個の意味であり、それらの異なるサブセットは、非推奨の異なるものに適用されます。そして、それらのサブセットのいくつかは、非推奨ではないものに適用されます(ただし、非推奨になる可能性があります)。

CloneableObject.clone()は、設計上の欠陥があり、正しく使用するのが難しいという意味で「壊れています」。ただし、clone()は依然として配列をコピーする最良の方法であり、クローニングには、慎重に実装されたクラスのインスタンスのコピーを作成するためのいくつかの限られた有用性があります。クローンの削除は互換性のない変更であり、多くのことを壊してしまいます。クローン操作は別の方法で再実装できますが、おそらくObject.clone()よりも遅いでしょう。

ただし、ほとんどの場合、複製よりもコピーコンストラクタの方が適しています。したがって、おそらくCloneableを「廃止」または「置換」または同様の何かとしてマークすることが適切でしょう。これにより、開発者はおそらく他の場所を見たいと思うようになりますが、将来のリリースでクローン作成メカニズムが削除される可能性はありません。残念ながら、そのようなマーカーは存在しません。

現状では、「非推奨」とは、廃止された機能がわずかに削除されているという事実にもかかわらず、最終的には削除されることを意味しているようです。したがって、非推奨はクローンメカニズムに保証されません。おそらく将来的には、代わりの代替メカニズムを使用するように開発者に指示する代替マーキングを適用できます。

[〜#〜] update [〜#〜]

バグレポート に追加の履歴を追加しました。初期のJVM実装者であり、JVM仕様の共著者であるFrank Yellinは、 その他の回答 で引用されたTRC勧告の「失われた霧」のコメントに応えてコメントをしました。ここで関連する部分を引用しました。完全なメッセージはバグレポートにあります。

Cloneableには、Serializableにはない同じ理由でメソッドがありません。 Cloneableは、クラスがサポートするメソッドについて何も具体的に言うのではなく、クラスのプロパティを示します。

リフレクションの前に、Objectの浅いコピーを作成するネイティブメソッドが必要でした。したがって、Object.clone()が生まれました。また、多くのクラスがこのメソッドをオーバーライドしたいこと、およびすべてのクラスを複製したいわけではないことも明らかでした。したがって、Cloneableはプログラマの意図を示すために生まれました。

つまり、要するに。 Cloneableの目的は、パブリックclone()メソッドがあることを示すことではありません。 Object.clone()を使用してクローンを作成する意思があることを示すためであり、clone()をパブリックにするかどうかを決定するのは実装次第でした。

63
Stuart Marks