IntelliJ IDEA报告合同违规警告

时间:2015-02-12 18:31:21

标签: java intellij-idea

这是Java代码:

public static boolean anyEqual(Object needle, Object... haystack) {
    if(needle == null || haystack == null) {
        return false;
    }
    if(haystack.length == 0) {
        return false;
    }
    for(Object match : haystack) {
        if(match != null && needle.getClass() == match.getClass() && needle.equals(match)) {
            return true; // warning from IntelliJ here, 'contract clause !null, null -> false is violated'
        }
    }
    return false;
}

有没有人知道为什么会这样? contract clause !null, null -> false is violated?谢谢!

IntelliJ 14.0.2 build:139.659

屏幕截图:enter image description here

3 个答案:

答案 0 :(得分:5)

IntelliJ推断出你的方法的正式contract

null, _ -> false; !null, null -> false

这实际上意味着什么:

  • 第一个合同指定,只要第一个参数为null,它就会返回false。这可以通过您的第一个if声明来观察:

    if(needle == null || haystack == null) {
        return false;
    }
    
  • 第二个合同指定,如果第二个参数为null,则它将返回false。这也由上面的if语句指定。

我的直觉告诉我,除了上述所有内容之外,IntelliJ在识别循环正式合同方面遇到了一些麻烦,尽管它与合同表达中的另一个条件一样简单。

for(Object match : haystack) {
    if(match != null && needle.getClass() == match.getClass() && needle.equals(match)) {
        return true;
    }
}

让我们简要介绍一下。

  • 如果haystack长度为0,则增强型for语句不会触发,因此需要考虑。
  • 数组内部的元素可能是null,我还不完全确定IntelliJ的静态分析是否涵盖了该部分。
  • 我们已经确定needle必须是非空的,所以没有违反合同的行。
  • 如果我们的某个方案match != null && needle.getClass() == match.getClass() && needle.equals(match)true,我们会返回true。否则,我们会返回false

nothing that I can see in the formal documentation为我们提供了我们需要说的表达式,"嘿 - 我们正在检查数组的元素!&#34 ;;可能情况是,尽管我们上面已经说明了(因为true非空),但分析正在tri我们返回haystack这一事实。

请允许我强调这一点:

haystack必须是非null,才能进入增强版。您的代码将不起作用。

总而言之,我不担心。更好的是,提交一个针对它的错误,以便可以修复或扩展此类事情。

答案 1 :(得分:1)

这看起来像是一个IntelliJ错误,因为通过从方法中删除static关键字警告消失。

这里必须混淆静态分析。人们可以随时将此提交给你跟踪,所以jetbrains开发人员可以查看它。

有人已经报告了此问题Here

(在v14.0.3上测试)

答案 2 :(得分:-3)

显示此消息是因为IntelliJ检查方法合同违规。这是一个相对较新的功能,请参阅https://www.jetbrains.com/idea/features/annotation_java.html