我有一个可以返回null值的函数。所以我使用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检查员中的错误吗?
答案 0 :(得分:4)
检查员并非完全错误。在这种情况下,您可能会NullPointerException
:因为您每次都在调用Service.getConnectionManager()
,所以我们无法绝对确定它不会返回{ {1}}第二次,即使它不是第一次:getter可能有比null
更复杂的逻辑,或者变量可能在两个方法调用之间同时设置为return ...
。
因此,您可以将代码重构为:
null
假设ConnectionManager manager = Service.getConnectionManager();
if (manager != null) {
manager.onAssetInfoChanged();
}
的返回类型是getConnectionManager()
类型的对象。有了这个,就不可能在该行上有ConnectionManager
。
答案 1 :(得分:3)
问题是您要两次拨打Service.getConnectionManager()
。在实际使用它的第二次调用时,Lint必须假设它现在可以为null。解决此问题的一种方法是使用这样的局部变量:
ConnectionManager connectionManager = Service.getConnectionManager();
if(connectionManager != null) {
connectionManager.onAssetInfoChanged();
}
另一种选择,在我看来,首选的方法是首先避免空值。如果您使用的是Java 8,则可以使用Optional
来表示您的ConnectionManager
可以为空的事实。
最好的方法是确保ConnectionManager
实际上永远不会null
答案 2 :(得分:1)
首先,@Nullable
与可以为null的方法参数相关。相反的是NotNull
,这意味着必须设置参数。其次,getConnectionManager
的每次调用都由分析器单独处理。这样做
ConnectionManager connManager = Service.getConnectionManager();
if(connManager != null
{
//do your stuff
}