为什么IDEA报告可能的NullPointerException?

时间:2017-08-15 21:15:50

标签: java intellij-idea nullpointerexception

为什么使用辅助变量进行空检查以防止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的{​​{1}}辅助变量,而方法p直接检查null。

当找不到合适的passwordMatch1实例时,已知方法LoggedPlayer.getLoggedPlayer(Player player)会返回null

IDEA正在LoggedPlayer报告警告:

  

方法调用'getPassword'可能产生   “显示java.lang.NullPointerException

虽然passwordMatch1没有警告。

IntelliJ IDEA Ultimate 2017.2

2 个答案:

答案 0 :(得分:7)

考虑LoggedPlayer.getLoggedPlayer的可能(但不好)实现。

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

也就是说,getLoggedPlayer可能不是纯粹的,对它的单独调用可能会返回不同的值。

答案 1 :(得分:1)

静态分析存在局限性。通常情况下,静态分析将无法可靠地检测并将您在安全检查中包含潜在不安全操作的情境化。

Lexers很简单。他们会将他们看到的每个符号都标记出来,并从那里开始。从那里,他们将无法说,“哦,我们已经检查了这个调用”,他们将无法可靠地报告其安全性。

另一个问题是,如果您的方法不是幂等的,那么在静态分析中确定 不能 的事实。如果LoggedPlayer.getLoggedPlayer(player)在任何给定的调用中返回了不同的值(例如在@Nick的奇妙示例中),则词法分析器将错过对该案例的报告。