Java 8 のデフォルト メソッドはユーザー コードを破壊しますか?
一見すると、デフォルトのメソッドは Java 仮想マシンの命令セットに多くの新機能をもたらします。最終的に、ライブラリ開発者は、クライアント コードとの互換性の問題を引き起こすことなく API をアップグレードできるようになります。デフォルト メソッドを使用すると、ライブラリ インターフェイスを実装するクラスは、そのインターフェイスによって導入されたデフォルト メソッドに自動的に適応します。ユーザーが実装したクラスを更新すると、元のデフォルト メソッドをより意味のあるメソッドで簡単にオーバーライドできます。さらに良いことに、ユーザーはメソッドをオーバーライドするときにインターフェイスのデフォルト実装を呼び出し、ビジネス ロジックを追加できます。 ######ここまでは順調ですね。ただし、インターフェイスの作成時にデフォルトのメソッドを追加すると、Java コードの互換性がなくなる可能性があります。これは、以下の例から簡単に理解できます。ライブラリが入力としてインターフェイスの 1 つを必要とすると仮定します。
interface SimpleInput { void foo(); void bar(); } abstract class SimpleInputAdapter implements SimpleInput { @Override public void bar() { // some default behavior ... } }
Java 8 より前は、インターフェイスとアダプター クラスを併用する上記の方法と同様、これは Java プログラミングで非常に一般的な設計パターンでした。言語。 。このアダプターは通常、ライブラリーのユーザーが特定の操作を省略できるようにするために、ライブラリー・プロバイダーによって提供されます。ただし、インターフェイスの形式で提供される場合は、多重継承を許可するのと似ています。
さらに、ユーザーが次のアダプターを使用すると仮定します:
class MyInput extends SimpleInputAdapter { @Override public void foo() { // do something ... } @Override public void bar() { super.bar(); // do something additionally ... } }
この実装により、最終的にライブラリと対話できるようになります。 bar メソッドをオーバーライドし、デフォルトの実装に機能を追加する方法に注目してください。
このライブラリを Java 8 に移植するとどうなりますか?まず、ライブラリはアダプター クラスを非推奨にし、デフォルトのメソッドを使用してこの機能を提供する可能性が高くなります。最終的に、インターフェイスは次のようになります。
interface SimpleInput { void foo(); default void bar() { // some default behavior } }
この新しいインターフェイスを使用すると、ユーザーは元のアダプター クラスの代わりにデフォルトのメソッドを使用するようにコードを更新できます。アダプター クラスの代わりにインターフェイスを使用すると、最終的には、そのクラスが特定のアダプターではなく他のクラスを拡張できるようになります。次に、デフォルトのメソッドを使用するために MyInput クラスを練習して移植しましょう。他のクラスを拡張できるようになったので、サードパーティの基本クラスを拡張します。ここではこの基本クラスの役割を気にする必要はありません。これが私たちの関数にとって意味があると想定できます。
class MyInput extends ThirdPartyBaseClass implements SimpleInput { @Override public void foo() { // do something ... } @Override public void bar() { SimpleInput.super.bar(); // do something additionally ... } }
元のクラスと同様の機能を実現するために、Java 8 の新しい構文を使用して、指定されたインターフェイスのデフォルト メソッドを呼び出します。同時に、メソッド内のロジックの一部を基本クラスに移動します。この時点で、あなたは私の肩をたたいて、これは非常に優れたリファクタリングだと言うかもしれません。
私たちはこのライブラリを非常にうまく使用してきました。ただし、メンテナは、より多くの機能を提供するには、別のインターフェイスを追加する必要があります。このインターフェイスは、SimpleInput インターフェイスを継承し、新しいメソッドを追加する ComplexInput インターフェイスに置き換えられます。デフォルト メソッドは一般に安全に追加できるため、メンテナは SimpleInput のデフォルト メソッドをオーバーライドして、より優れたデフォルト メソッドを提供しました。結局のところ、これはアダプター クラスでよく行われることです。
interface ComplexInput extends SimpleInput { void qux(); @Override default void bar() { SimpleInput.super.bar(); // so complex, we need to do more ... } }
新機能は非常に良い結果をもたらしたので、ThirdPartyBaseClass を保守している人々もこのライブラリに依存することにしました。このジョブを実行するために、ThirdPartyLibrary に ComplexInput インターフェイスを実装します。
しかし、これは MyInput クラスにとって何を意味するのでしょうか? ComplexInput インターフェイスを暗黙的に実装するには、ThirdPartyBaseClass クラスを継承できますが、SimpleInput のデフォルト メソッドの呼び出しは突然不正になります。その結果、ユーザーのコードはコンパイルに失敗します。 Java では、直接ではないサブクラスから親クラスのメソッドを呼び出すことは違法であるとみなされるため、この種の呼び出しは現在禁止されています。このデフォルト メソッドは ComplexInput でのみ呼び出すことができますが、そのためにはこのインターフェイスを MyInput で明示的に実装する必要があります。ライブラリのユーザーにとって、この変更は予期されていません。
さらに奇妙なのは、Java ランタイムにはそのような制限が課されていないことです。 JVM のバリデーターを使用すると、クラスが更新された ThirdPartyBaseClass を継承している場合でも、コンパイルされたクラスが SimpleInput::foo メソッドを呼び出すことができるため、暗黙的に ComplexClass が実装されます。この制限はコンパイラにのみ存在します。
以上がJava 8 のデフォルト メソッドはユーザー コードを破壊しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック

Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

Java のアームストロング番号に関するガイド。ここでは、Java でのアームストロング数の概要とコードの一部について説明します。

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです
