2010-05-14 68 views
6

在Java中,我定義了一個具有抽象方法和抽象方法的抽象類,它必須由第三方開發人員獨立進行子類化。可以肯定的是:我可以對抽象類做出什麼改變,它們與源類兼容,但不兼容二進制文件?換句話說:在他們編寫了他們的子類之後,我能否改變抽象類 - 除了例如給它添加一個抽象方法或從中移除一個被子類調用的受保護方法,這種方法當然是源不兼容的 - 這可能會迫使它們重新編譯它們的子類?Java - 抽象類和子類的二進制兼容性

回答

8

如果不是太晚改變你的系統類,我建議你這樣做。重寫通常不是定製功能的好方法,因爲它非常脆弱。例如,如果以後使用客戶使用的方法名稱(他們現在無意中自動覆蓋),則覆蓋可能會徹底破壞類的不變量。提供定製的一種更好的方式是給客戶一個僅限於自定義行爲的界面,然後你有一個完全具體的類,它依賴於這個界面的一個實例,並在需要時適當地委託給界面使用自定義行爲。這樣,你的代碼和客戶端的代碼就完全分開了,它們不會互相干擾。

+0

感謝您也提供替代!那也是我正在考慮的 - 我正在考慮複雜性的成本(保持對實現的參考並委託給它),但由於這個可插拔體系結構是一項要求,我會這樣做。 – thSoft 2010-05-16 09:41:28

2

當然。

您可能意外地使用了他們使用的方法名稱,現在它突然被覆蓋,結果可能會有很大差異。

您可以字段添加到其陷入困境的序列化等

5

我假設您在技術意義上使用「二元不兼容」例如類加載器檢測到不兼容性並拒絕加載類。如果你增加了一個明顯的方法宣佈它final,並且該方法與現有的一些方法在第三方子簽名相撞,也可以引入

二進制不兼容。但是,如果方法不是最終的,現有的方法將變成可能導致問題的(新)方法的覆蓋,但不是二進制不兼容。

同樣,添加新的可見字段會導致隱藏,可能會導致混淆行爲並破壞對象序列化。但是這不會導致二進制不兼容。

一般而言,這意味着您需要考慮應用程序語義問題以及簡單的二進制兼容性。 Java類型系統不會幫助你。

爲了完整起見,也有其他的事情,你可以在你的代碼做會破壞二進制兼容性的第三方類:

  • 減少你的抽象類和/或它的方法的知名度,
  • 變化作爲參數,結果和異常類型的其他類的簽名,
  • 變化,你的抽象類擴展超類鏈,或使這些類中的不兼容的更改,或
  • 變化的界面T樹您的抽象類實現,或在這些接口中進行不兼容的更改。
+0

感謝您提供全面的答案,以及思考我也想到但未描述的內容,即任何其他方式來打破執行者的代碼。 – thSoft 2010-05-16 09:36:07

+0

很好的答案。二進制和源代碼兼容性的規則相互獨立。分開理解它們很重要。 http://motlin.com/2010/binary-and-source-backwards-compatibility/ – 2010-11-26 16:58:47