Java IntelliJ IDEA报告违反合同警告

Java IntelliJ IDEA报告违反合同警告,java,intellij-idea,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) {

以下是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;
}
有人知道为什么会出现这种情况吗<代码>合同条款!null,null->false被违反?谢谢

IntelliJ 14.0.2版本:139.659


屏幕截图:

显示此消息是因为IntelliJ检查方法契约冲突。这是一个相对较新的功能,请在

阅读更多信息IntelliJ推断您的方法的形式如下:

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
这给了我们一个表达式,我们需要说,“嘿,我们正在检查数组的元素!”;可能的情况是,尽管我们在上面提到过(因为haystack是非空的),但我们返回的是
true
,这一事实使分析出错

请允许我强调这一点:

haystack
必须为非
null
,才能进入增强的for。否则,您的代码将无法工作


总而言之,我不会担心的。更好的办法是,针对它提交一个bug,以便修复或扩展此类问题。

我觉得这就像IntelliJ bug,因为从方法中删除
static
关键字,警告就会消失

这里的静态分析肯定有点混乱。你可以把它提交给youtrack,这样jetbrains开发者就可以查看它了

有人已经报告了这个问题


(在v14.0.3上测试)

该方法上面有任何注释吗?看起来,在14.1 EAP中修复或更改了返回类型Boolean,并且返回Boolean.TRUE,它也将消失。因此,是的,我们可以理解它是一个功能。我们想了解的是它为什么会这样。到IntelliJ合同注释文档的链接已断开@弗拉文:谢谢,但以后你可以建议编辑。我很可能已经同意了。