2017-08-15 2 views
1

Warum ist Null-Überprüfung mit Hilfsvariable Schutz vor NullPointerException, während direkte Nullprüfung nicht ist?Warum meldet IDEA mögliche NullPointerException?


Betrachten Sie diese zwei Codeblöcke:

public boolean passwordMatch1(Player player, String password) { 
    if (LoggedPlayer.getLoggedPlayer(player) != null) { 
     return LoggedPlayer.getLoggedPlayer(player).getPassword().equals(password); 
    } 
    return false; 
} 

und

public boolean passwordMatch2(Player player, String password) { 
    LoggedPlayer p = LoggedPlayer.getLoggedPlayer(player); 
    if (p != null) { 
     return p.getPassword().equals(password); 
    } 
    return false; 
} 

Sie sind genau das gleiche tun, Verfahren passwordMatch2 verwendet Hilfsvariable von LoggedPlayerp genannt, während Methode passwordMatch1 prüft direkt auf null.

Methode LoggedPlayer.getLoggedPlayer(Player player) ist bekannt, null zurückgeben, wenn keine entsprechende LoggedPlayer Instanz gefunden wird.


IDEA meldet eine Warnung in passwordMatch1:

Method Invocation 'getPassword' erzeugen kann ‚java.lang.NullPointerException

während passwordMatch2 keine Warnung hat.

(IntelliJ IDEA Ultimative 2017,2)

+4

Wenn die zugrunde liegende 'LoggedPlayer.getLoggedPlayer()' -Datenstruktur zwischen Aufrufen wechseln kann (wie in einem Multithread-Kontext), könnte der zweite Aufruf in 'passwordMatch1' einen Nullwert zurückgeben. – billie

Antwort

7

Betrachten wir eine mögliche (aber schlecht) Umsetzung von LoggedPlayer.getLoggedPlayer.

public static LoggedPlayer getLoggedPlayer(Player player) { 
    return Math.random() < 0.500 ? new LoggedPlayer() : null; 
} 

Das heißt, getLoggedPlayer kann nicht rein sein und separate Anrufungen davon können unterschiedliche Werte ergeben.

1

Es gibt Einschränkungen in der statischen Analyse. Normalerweise ist die statische Analyse nicht in der Lage, zuverlässig zu erkennen und zu kontextualisieren, dass Sie einen potenziell unsicheren Vorgang in eine sichere Prüfung eingeschlossen haben.

Lexer sind einfach. Sie werden jedes Symbol, das sie sehen, mit einem Token versehen und von dort aus gehen. Von dort werden sie nicht sagen können: "Oh, wir haben diese Invokation bereits überprüft", und sie werden nicht in der Lage sein, zuverlässig über ihre Sicherheit zu berichten.

würde Ein weiteres Problem, wenn Ihre Methode eine Tatsache war nicht idempotent, dass kann in der statischen Analyse nicht bestimmt werden. Wenn LoggedPlayer.getLoggedPlayer(player) bei einem bestimmten Aufruf einen anderen Wert zurückgegeben hat (z. B. in @ Nicks fantastischem Beispiel), würde der Lexer es versäumen, über diesen Fall zu berichten.

Verwandte Themen