3

我有一个可以返回空值的函数。所以我使用了 JetBrains 注释,并@Nullable在函数顶部添加了注释。

@Nullable
public static ConnectionManager getConnectionManager() {
    return connectionManager;
}

然后,我进行了 Lint 检查。当我使用这个功能时,我发现了 4 个地方,并且我没有做任何空值检查。

前:

Service.getConnectionManager().onAssetInfoChanged();

后:

if(Service.getConnectionManager() != null) {
    Service.getConnectionManager().onAssetInfoChanged();
}

然后我再次运行 Lint 检查。令我惊讶的是,我仍然得到:

Service.getConnectionManager().onAssetInfoChanged()第 308 行的方法调用' '可能会产生' java.lang.NullPointerException'。

我究竟做错了什么?这是 Lint 检查器中的错误吗?

4

3 回答 3

5

检查员并没有完全错。在这种情况下你可能有一个NullPointerException:因为你每次都在调用Service.getConnectionManager(),所以我们无法绝对确定它不会null第二次返回,即使它不是第一次:getter 可能有一个比return ...或变量更复杂的逻辑可能已null在两个方法调用之间同时设置。

因此,您可以将代码重构为:

ConnectionManager manager = Service.getConnectionManager();
if (manager != null) {
    manager.onAssetInfoChanged();
}

假设的返回类型getConnectionManager()是类型的对象ConnectionManager。有了这个,就不可能NullPointerException在那条线上有一个。

于 2016-01-14T15:12:30.377 回答
3

问题是你打Service.getConnectionManager()了两次电话。在您实际使用它的第二次调用时,Lint 必须假设它现在可能为空。解决这个问题的一种方法是使用这样的局部变量:

ConnectionManager connectionManager = Service.getConnectionManager();
if(connectionManager != null) {
    connectionManager.onAssetInfoChanged();
}

另一种方法,在我看来,首选方法是首先避免空值。如果您使用的是 Java 8,则可以使用 anOptional来表示您ConnectionManager可以为 null 的事实。

最好的方法是确保您ConnectionManager实际上永远不会null

于 2016-01-14T15:12:36.650 回答
1

首先,@Nullable与可以为空的方法参数有关。相反,NotNull这意味着必须设置参数。其次,每个调用getConnectionManager都由分析器单独处理。像这样做

ConnectionManager connManager = Service.getConnectionManager();
if(connManager != null
{
//do your stuff
}
于 2016-01-14T15:12:43.013 回答