2017-08-15 147 views
1

爲什麼使用輔助變量進行空檢查針對NullPointerException進行保護,而直接空檢查不是?爲什麼IDEA報告可能存在NullPointerException?


考慮這些代碼兩大塊:

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

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

他們正在做同樣的事情,方法passwordMatch2使用的LoggedPlayer稱爲p輔助變量,而方法passwordMatch1直接檢查null。

方法LoggedPlayer.getLoggedPlayer(Player player)已知當找不到合適的LoggedPlayer實例時返回null


想法是在passwordMatch1報告警告:

方法調用 'getPassword來' 可能會產生 「顯示java.lang.NullPointerException

passwordMatch2沒有警告。

的IntelliJ IDEA終極2017.2

+4

如果底層的'LoggedPlayer.getLoggedPlayer()'數據結構能夠在不同的調用之間進行切換(如在多線程上下文中),那麼'passwordMatch1'中的第二次調用可能會返回空值。 – billie

回答

7

考慮是否有可能(但壞)實施LoggedPlayer.getLoggedPlayer

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

也就是說,getLoggedPlayer可能不是純的,並且它的單獨調用可能會返回不同的值。

1

靜態分析存在侷限性。通常情況下,靜態分析將無法可靠地檢測並上下文化您已在安全檢查中封裝了潛在的不安全操作。

詞庫很簡單。他們會標記他們看到的每一個符號,並從那裏開始。從那裏,他們將不能說「哦,我們已經檢查過這個調用」,他們將無法可靠地報告其安全性。

的另一個問題是,如果你的方法不是冪,即無法靜態分析來確定的事實。如果LoggedPlayer.getLoggedPlayer(player)在任何給定的調用上返回不同的值(例如在@ Nick的奇妙例子中),那麼詞法分析器將錯過關於該情況的報告。

相關問題