简体   繁体   中英

IntelliJ IDEA Reporting Contract Violation Warning

Here is the Java code:

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;
}

Does anyone have any idea why this is being shown? contract clause !null, null -> false is violated ? Thanks!

IntelliJ 14.0.2 build: 139.659

Screenshot: 在此输入图像描述

IntelliJ is inferring the formal contract of your method to be this:

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

What this actually means:

  • The first contract specifies that, so long as the first parameter is null , it will return false . This is observed by your first if statement:

     if(needle == null || haystack == null) { return false; } 
  • The second contract specifies that, if the second parameter is null , then it will return false . This is also specified by the same if statement above.

My gut is telling me that IntelliJ is having some trouble discerning what the loop's formal contract is in addition to all of the above, although it'd be as simple as another condition in the contract expression.

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

Let's briefly go through this.

  • The enhanced-for statement won't fire if haystack is of length 0, so that's something to take into consideration.
  • The elements inside of the array could be null , and I'm not entirely sure that IntelliJ's static analysis covers that piece yet.
  • We've established already that needle must be non-null, so there's nothing violating the contract at that line.
  • If we have a scenario in which match != null && needle.getClass() == match.getClass() && needle.equals(match) is true , we return true . Otherwise, we return false .

There's nothing that I can see in the formal documentation that gives us the expression we require to say, "hey - we're checking elements of an array!"; it may be the case that the analysis is tripping up on the fact that we're returning true in spite of what we stated above (since haystack is non-null).

Allow me to stress this point:

haystack has to be non- null in order for you to enter into the enhanced-for. Your code will not work otherwise.

All in all, I wouldn't worry about it. Better yet, file a bug against it so that this sort of thing could be fixed or expanded upon.

This looks like an IntelliJ bug to me, since by removing the static keyword from the method the warning disappears.

Something must be confusing the static analysis here. One can always submit this to youtrack so jetbrains devs can look at it.

Someone already reported this issue Here

(tested on v14.0.3)

This message is being shown because IntelliJ checks for method contract violations. It's a relatively new feature, read more at https://www.jetbrains.com/idea/features/annotation_java.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM