【问题标题】:What is the correct way to implement compareObjects()实现 compareObjects() 的正确方法是什么
【发布时间】:2011-11-06 21:53:27
【问题描述】:

我有如下实现的 compareObjects 方法

public static int compareObjects(Comparable a, Comparable b){

        if (a == null && b == null){
            return 0;
        } else if (a == null && b != null){
            return -1;
        } else if (a != null && b == null){
            return 1;
        } else {
            return a.compareTo(b);
        }
    }

当我通过 findBugs 运行它时,我在return a.compareTo(b) 这条线上得到了这个建议:

有一个语句分支,如果执行,则保证将取消引用空值,这将在执行代码时生成 NullPointerException。当然,问题可能是分支或语句不可行,空指针异常永远无法执行;决定这超出了 FindBugs 的能力。由于该值之前已针对空值进行过测试,因此这是一种确定的可能性。

此时a 永远不能为空。为什么 FindBugs 会向我显示此建议?我该如何纠正这个;实现compareObjects()的正确方法是什么?

【问题讨论】:

  • 从描述中,听起来它不喜欢这样一个事实,即如果其中一个为空,则对象是不同的(如果 a == null,IE 返回 -1 , 这掩盖了 a == null) 的事实。
  • Comparable 是一个泛型类型。 A和B的类型参数一样吗?否则,您可能会在运行时遇到一些有趣的错误,因为 compareTo 仅用于在具有相同类型的对象上调用。另外,为什么你首先需要这个辅助方法?当一个元素为空时提供排序?
  • 静态分析工具并非万无一失——它们有时会而且确实会产生误报

标签: java compare


【解决方案1】:

这可能是 FindBugs 的限制;我同意您已经涵盖了所有基础,但是您的空检查分为两个不同的条件。现在这些条件恰好是互补的,所以如果a 为空,它们中的至少一个会触发,但根据 FindBugs 的复杂程度,它可能无法识别这一点。

这里有两个选项,那么:

  1. 忽略 FindBugs 警告。由于其性质,它会不时引发一些误报,所以如果你认为重写不值得,不要觉得你必须重写你的代码来让它 100% 快乐就其自身的优点而言。

    如果您希望报告最后显示一个漂亮的大零,您可以使用@SuppressWarnings annotation 将其实际传达给 FindBugs。示例见this question。

  2. 通过嵌套 if 块,重构条件,以便对 a 的无效性检查更加明确:

    if (a == null) {
       return b == null ? 0 : -1;
    }
    return b == null ? 1 : a.compareTo(b);
    

    根据您的品味和风格,可能会更好地重写,因为更清楚地说“如果a 为空,则执行 this 计算并返回它,否则执行 这个计算”。如果您愿意,当然可以将三元条件更改为另一个 if-else 块。

【讨论】:

  • 谢谢 Andrzej,是的,没有必要重写我的代码来让 findBugs 100% 满意 :) 我喜欢你的说法。
【解决方案2】:

再看一遍,试试这段代码:

if (a == null && b == null){
    return 0;
} 

if (a == null){
    return -1;
} 

if (b == null){
    return 1;
} 

return a.compareTo(b);

【讨论】:

    【解决方案3】:

    我认为这可能是因为您不需要额外的 && 语句。在第一个 if 语句之后,您已经知道其中一个为空。

    public static int compareObjects(Comparable a, Comparable b){
    
        if (a == null && b == null){
            return 0;
        } else if (a == null){
            return -1;
        } else if (b == null){
            return 1;
        } else {
            return a.compareTo(b);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-20
      • 2011-02-23
      • 2011-05-04
      • 2014-04-07
      • 1970-01-01
      相关资源
      最近更新 更多