2016-08-19 45 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时也是如此。

相关问题