簡體   English   中英

我可以使用子接口重新編譯公共API並保持二進制兼容性嗎?

[英]Can I recompile a public API with a sub-interface and keep binary compatibility?

我有一個公共API,在幾個項目中多次使用:

public interface Process<C extends ProcessExecutionContext> {

    Future<?> performAsync(C context);

}

還有一個抽象類,負責實現Future機制(未顯示)。 我知道所有項目都是相應的抽象類的子類(對於這些抽象類,performAsync是最終的 ),並且沒有單個類在沒有子類化抽象實現者的情況下實現抽象接口。 這是設計上的,因為這個“公共”API在我們公司內是“公開的”。

與Spring的ListenableFuture相比,發現Future太有限了我決定將界面擴展到

public interface Process<C extends ProcessExecutionContext> {

    ListenableFuture<?> performAsync(C context);

}

我已經在示例中未顯示的單個抽象超類中實現了ListenableFuture。 根據設計,沒有其他實現存在。

到目前為止,每個調用者都使用Future ,它是ListenableFuture的超級ListenableFuture 如果使用Future<?> future = processReturningListenable.performAsync(context)代碼編譯得很好。

問題是:如果我部署的公共API的跟上時代的JAR,包含兩種接口,並與抽象超ListenableFuture落實到現有環境, 而無需重新編譯所有的項目 ,並在performAsync電話仍然有效?

即,當接口被返回原始類型的子類型的方法替換時,Java是否授予接口的二進制兼容性?

我問這個是因為1)我發現沒有人可以使用現有的JAR文件進行簡單測試,2)必須重新編譯所有項目是一個紅色警報。

我假設我的要求是可能的,因為Java方法名稱由一個計算方法名稱和輸入參數的簽名來標識。 更改輸出參數不會更改方法的名稱

這已在Java®語言規范§13中直接解決 二進制兼容性,§13.4.15。 方法結果類型

改變的方法的結果類型,或與替換結果類型void ,或替換void與結果類型,具有刪除舊方法和添加新方法與新的結果類型的或新的組合效果void結果(見§ 13.4.12 )。

引用的§13.4.12說:

...

從類中刪除方法或構造函數可能會破壞與引用此方法或構造函數的任何預先存在的二進制文件的兼容性; 當鏈接來自預先存在的二進制文件的此類引用時,可能會拋出NoSuchMethodError 僅當在超類中未聲明具有匹配簽名和返回類型的方法時,才會發生此類錯誤。

所以答案是,不,如果不打破與現有代碼的二進制兼容性,就不能這樣做。

從技術上講,假設方法僅通過名稱和參數類型來識別是完全錯誤的,在字節代碼級別上,它們總是通過名稱,參數類型返回類型來標識。

但請注意,上面的引用聲明“ 只有在超類中沒有聲明具有匹配簽名和返回類型的方法時才會發生此類錯誤 ”。 這指導了可能的解決方法:

interface LegacyProcess<C extends ProcessExecutionContext> {
    Future<?> performAsync(C context);
}
public interface Process<C extends ProcessExecutionContext> extends LegacyProcess<C> {
    @Override ListenableFuture<?> performAsync(C context);
}

現在, Process繼承了LegacyProcess的匹配方法,這是一種不需要導出的類型,然后根據需要使用更具體的返回類型覆蓋它。 這被稱為“共變型返回類型”。 在字節代碼級別,將有一個“ Future performAsync(…) ”方法,該方法委托給實際的實現方法“ ListenableFuture performAsync(…) ”。 這種自動生成的委托方法稱為橋接方法

這樣,現有的編譯客戶端代碼繼續工作,而每個重新編譯的代碼將直接使用新方法而不使用橋接方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM