Javaでは、具象メソッドと抽象メソッドの両方を含む抽象クラスを定義しており、サードパーティの開発者が独自にサブクラス化する必要があります。念のために言っておきますが、抽象クラスにソース互換性はあるがバイナリ互換性はない変更を加えることはできますか?言い換えれば、サブクラスをコンパイルした後、抽象クラスを変更できますか?たとえば、抽象メソッドを追加したり、サブクラスによって呼び出される保護されたメソッドを削除したりすることはできませんが、もちろんソースとは互換性がありませんそれは彼らに彼らのサブクラスを再コンパイルすることを強制することができますか?
3 に答える
システムを変更するのに遅すぎない場合は、変更することをお勧めします。オーバーライドは非常に壊れやすいため、通常、機能をカスタマイズする良い方法ではありません。たとえば、クライアントが使用したメソッド名を後で使用する場合 (意図せずに自動的にオーバーライドしている)、オーバーライドによってクラスの不変条件が完全に壊れる可能性があります。通常、カスタマイズを提供するより良い方法は、カスタマイズされた動作のみに限定されたインターフェースをクライアントに提供することです。その後、このインターフェースのインスタンスに依存する完全に具体的なクラスを作成し、必要に応じてインターフェースに適切に委譲します。カスタマイズされた動作を使用します。このように、あなたのコードとクライアントのコードは完全に分離され、互いに干渉することはありません。
技術的な意味で「バイナリ非互換性」を使用していると想定しています。たとえば、クラスローダーが非互換性を検出し、クラスのロードを拒否する場合。
可視メソッドを追加して宣言しfinal
、そのメソッドがサードパーティのサブクラスの既存のメソッドのシグネチャと衝突した場合にも、バイナリの非互換性が発生する可能性があります。ただし、メソッドが非最終的なものである場合、既存のメソッドは (新しい) メソッドのオーバーライドに変わり、問題が発生する可能性がありますが、バイナリの非互換性はありません。
同様に、新しい可視フィールドを追加すると非表示になり、動作が混乱したり、オブジェクトのシリアル化が壊れたりする可能性があります。ただし、これによりバイナリの非互換性が生じることはありません。
一般に、これは、単純なバイナリ互換性だけでなく、アプリケーションのセマンティックの問題も考慮する必要があるという事実を示しています。そして、Java 型システムは役に立ちません。
完全を期すために、サード パーティ クラスのバイナリ互換性を損なう可能性のあるコードで実行できる他のことがあります。
- 抽象クラスおよび/またはそのメソッドの可視性を減らします。
- パラメーターの結果と例外の型として使用される他のクラスのシグネチャを変更します。
- 抽象クラスが拡張するスーパークラスのチェーンを変更するか、それらのクラスに互換性のない変更を加えます。
- 抽象クラスが実装するインターフェイスのツリーを変更するか、それらのインターフェイスに互換性のない変更を加えます。
もちろん。
彼らが使用したメソッド名を誤って使用することがあり、それが突然オーバーライドされて、おそらく劇的に異なる結果になることがあります。
シリアライゼーションなどを台無しにするフィールドをクラスに追加できます。