将返回类型从Integer更改为int,而不会破坏向后兼容性

时间:2016-08-19 14:06:15

标签: java

我正在某个Java 7 API上做QA,这是公开使用的开源。我的Clirr报告会检查向后API兼容性。我收到了以下错误:

[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的返回类型从Integer更改为int,并且Bar的返回类型已从byte更改到short。方法签名保持不变,因此不能选择重载。

  1. 这是否真的打破了向后兼容性?或者Clirr给我一个误报?
  2. 如何展开向后兼容性?如果不引入新的方法名称,这是否可行?
  3. 我还有其他一些关于返回类型更改的错误(大多数是voidfloat),但它们都在protected方法中,所以我将忽略它们

3 个答案:

答案 0 :(得分:5)

它明显打破了向后兼容性,因为您的API用户可能拥有以下代码:

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

从现在开始不会编译。

考虑到getAnchorData()的新版本返回了更多的值,您无法在不破坏向后兼容性的情况下执行转换,因为客户端的旧代码可能不适合接受所有可能的值。

关于你的上一次发言:

  

我还有一些关于返回类型更改的错误(大多数是浮动的空洞),但它们都在受保护的方法中,所以我将忽略它们。

如果这些方法属于publicfinal类,那么您也可以通过这样做来打破向后兼容性。

答案 1 :(得分:1)

在结果取消装箱完成后,向前兼容性肯定会被打破,因为表达式堆栈是打字的。

第二个问题是:针对新API的重新编译是否足够并且不会出错。

Integer to int,虽然更好的样式现在可能传播样式警告对客户端软件中的整数使用。即使在java 8中推断类型时它也应该顺利,除非立即与null进行比较:

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

这是一个非常罕见的案例。

需要字节/短手动操作。还可以预期短值超出字节范围,或者对128到255之间的短值进行符号溢出。 只有当逻辑不变时,仍然在-128 .. 127中的值在功能上都很好。

虽然不可编辑,但必须对资料进行调整。

提供向后兼容性:

对于现有的二进制jar:保留旧函数@Deprecated和javadoc注释以用于新用法。当超出范围超出字节时抛出IllegalStateException。

答案 2 :(得分:1)

除了user3707125写的另一个问题可能是有人扩展你的类并覆盖你的方法。请考虑以下示例:

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

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

如果您将BaseClass中的返回类型更改为int,那么MyClass将出现编译错误。所以这打破了向后的兼容性。将字节更改为短时也是如此。