2015-02-12 18 views
7

Hier ist der Java-Code:IntelliJ IDEA Berichterstattung Vertragsverletzung Warnung

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

Hat jemand eine Ahnung, warum dies gezeigt wird? contract clause !null, null -> false is violated? Vielen Dank!

IntelliJ 14.0.2 Build: 139,659

Screenshot: enter image description here

+0

Gibt es eine Anmerkung über dem Verfahren? – vikingsteve

+0

@vikingsteve nein – jn1kk

+1

Sieht aus wie https://youtrack.jetbrains.com/issue/IDEA-136079, behoben in 14.1 EAP unter https://confluence.jetbrains.com/display/IDEADEV/IDEA+14.1+EAP –

Antwort

5

IntelliJ gelesen wird, um die formale contract Ihrer Methode Folgern, dies:

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

Was das eigentlich bedeutet:

  • Der erste Vertrag legt fest, Solange der erste Parameter null ist, wird false zurückgegeben. Dies wird durch die erste if Aussage beobachtet:

    if(needle == null || haystack == null) { 
        return false; 
    } 
    
  • Der zweite Vertrag legt fest, dass, wenn der zweite Parameter null ist, dann wird es false zurück. Dies wird auch durch die obige if Anweisung oben angegeben.

Mein Bauch sagt mir, dass IntelliJ einige Probleme erkennenden ist zu haben, was die formellen Vertrag der Schleife zusätzlich zu allen oben genannten ist, obwohl sie als eine weitere Bedingung im Vertrag Ausdruck so einfach sein würde.

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

Lassen Sie uns kurz durchgehen.

  • Die enhanced-for-Anweisung wird nicht ausgelöst, wenn haystack die Länge 0 hat, das ist also etwas, das berücksichtigt werden muss.
  • Die Elemente innerhalb des Arrays könnten null sein, und ich bin mir nicht ganz sicher, ob die statische Analyse von IntelliJ dieses Teil bereits abdeckt.
  • Wir haben bereits festgestellt, dass needle nicht null sein muss, also gibt es nichts, das den Vertrag in dieser Zeile verletzt.
  • Wenn wir ein Szenario haben, in dem match != null && needle.getClass() == match.getClass() && needle.equals(match)true ist, geben wir true zurück. Andernfalls geben wir false zurück.
  • Es gibt nothing that I can see in the formal documentation, die uns den Ausdruck gibt, den wir benötigen, um zu sagen, "hey - wir überprüfen Elemente eines Arrays!"; Es kann der Fall sein, dass die Analyse auf die Tatsache stolpert, dass wir true trotz dessen, was wir oben angegeben zurückgeben (seit haystack ist nicht null).

    Erlauben Sie mir, diesen Punkt zu betonen:

    haystack hat nicht null sein, um für Sie in die erweiterte-für einzugeben. Ihr Code wird sonst nicht funktionieren.

    Alles in allem würde ich mir keine Sorgen machen. Noch besser, füge einen Fehler ein, damit diese Art von Problem behoben oder erweitert werden kann.

    +0

    Der Link zur IntelliJ-Vertragsanmerkungsdokumentation ist beschädigt. [Aktuelle Version hier] (https://www.jetbrains.com/idea/help/contract-annotations.html). – Flavin

    +0

    @Flavin: Danke, aber in Zukunft könntest du eine Bearbeitung vorschlagen. Ich hätte das wahrscheinlich genehmigt. – Makoto

    1

    Das sieht für mich wie ein IntelliJ-Fehler aus, da durch Entfernen des static-Schlüsselwortes aus der Methode die Warnung verschwindet.

    Etwas muss die statische Analyse hier verwirren. Man kann dies immer an youttrack übergeben, damit die Devices von Jetbrains es sehen können.

    Jemand berichtete bereits dieses Problem Here

    (auf v14.0.3 getestet)

    +0

    Oder ändern Sie den Rückgabetyp Boolean, und zurück Boolean.TRUE, es wird auch weggehen. – chenrui