2016-08-19 44 views
2

我正在對某個Java 7 API(即作爲開放源代碼在公共用途中)進行QA。我的Clirr報告檢查向後的API兼容性。我得到了以下錯誤:在不破壞向後兼容性的情況下將返回類型從Integer更改爲int

[ERROR] 7006: com.example.Foo: Return type of method 'public java.lang.Integer nameToUnicode(java.lang.String)' has been changed to int 
[ERROR] 7006: com.example.Bar: Return type of method 'public byte getAnchorDelta()' has been changed to short 

因此,這意味着我的開發人員改變了Foo返回類型從Integerint,而Bar返回類型從byte改爲short。方法簽名保持不變,所以超載不是一種選擇。

  1. 這是否真的打破向後兼容性?還是Clirr給我一個誤報?
  2. 如何解鎖向後兼容性?這甚至可能沒有引入新的方法名稱?

我有一個關於返回類型的變化(主要是一些void s到float)夫婦其他錯誤,但他們在protected方法,所以我會忽略它們。

+0

如果您希望保留向後兼容性,則需要保留相同的現有簽名。您可以添加新的API,但現有的API必須與之前的版本保持一致。 – ManoDestra

回答

5

這顯然打破了向後兼容性,您的API的用戶可能有類似代碼:

if (nameToUnicode("...").equals(4)) { ... } // no such method 
byte delta = getAnchorDelta(); // typecast required 

,不會從現在開始編譯。

考慮到getAnchorData()的新版本會返回更大的值,因此您不能在不破壞向後兼容性的情況下執行轉換,因爲客戶端的舊代碼可能不適合接受所有可能的值。

另外,關於你的最後一句話:

我有一個關於返回類型更改幾個其他錯誤(主要是一些空隙浮動),但他們是在保護的方法,所以我會忽略他們。

如果這些方法在publicfinal類中,那麼您也可以通過這樣做來打破向後兼容性。

1

向後兼容性肯定是壞的,因爲表達式堆棧是鍵入的,結果取消裝箱完成。

第二個問題是:針對新API的重新編譯是否足夠並且不會發生錯誤。

整數爲int,但更好的風格,現在可能在客戶端軟件使用整數繁殖樣式警告。推斷類型,在Java 8,即使它應該順利時,除應立即用空比較:

if (nameToUnicode("ĉarma") == null) 

這是一種非常罕見的情況。

隨着字節/短手動是必要的。也有人可能會期望超出字節範圍的短值,或者在128到255之間的短符號發生符號溢出。 只有在邏輯不變的情況下,值仍然在-128..127之間纔有效。

雖然不編譯,源必須進行調整。


提供向後兼容性:

對於現有二進制罐子:保留老功能,@Deprecated和javadoc註釋的新用法。當超出範圍時,拋出IllegalStateException異常。

1

除了什麼user3707125寫了另外一個問題,如果有人擴展類和重寫你的方法可能。考慮下面的例子:

public class BaseClass { 
    public Integer getInt() { 
     return 1; 
    } 
} 

public class MyClass extends BaseClass { 
    @Override 
    public Integer getInt() { 
     return null; 
    } 
} 

如果你改變了BaseClass的返回類型爲int然後MyClass的將有一個編譯錯誤。所以這打破了落後的兼容性。當你將字節改爲short時也是如此。

相關問題