为什么我在进行空值检查时仍会收到 IntelliJ 中可能存在 NPE 的警告?
Why do I still receive warning for possible NPE in IntelliJ when I do my null checking?
我有一个函数可以 return 空值。所以我使用了 JetBrains 注释并在函数顶部放置了一个 @Nullable
注释。
@Nullable
public static ConnectionManager getConnectionManager() {
return connectionManager;
}
然后,我 运行进行了 Lint 检查。当我使用这个函数时,我发现了 4 个地方,但我没有做任何 null 检查。
之前:
Service.getConnectionManager().onAssetInfoChanged();
之后:
if(Service.getConnectionManager() != null) {
Service.getConnectionManager().onAssetInfoChanged();
}
然后我运行再次检查Lint。令我大吃一惊的是,我仍然得到:
Method invocation 'Service.getConnectionManager().onAssetInfoChanged()
' at line 308 may produce 'java.lang.NullPointerException
'.
我做错了什么?这是 Lint 检查器中的错误吗?
检查员并没有完全错。在这种情况下,您可能会有一个 NullPointerException
:因为您每次都在调用 Service.getConnectionManager()
,所以我们无法绝对确定它不会 return null
第二次,即使不是第一次:getter 的逻辑可能比 return ...
更复杂,或者变量可能已在两个方法之间同时设置为 null
来电。
因此,您可以将代码重构为:
ConnectionManager manager = Service.getConnectionManager();
if (manager != null) {
manager.onAssetInfoChanged();
}
假设getConnectionManager()
的return类型是ConnectionManager
类型的对象。有了这个,就不可能在该行上有一个 NullPointerException
。
问题是您调用了 Service.getConnectionManager()
两次。在您实际使用它的第二次调用时,Lint 必须假设它现在可以为空。解决这个问题的一种方法是使用这样的局部变量:
ConnectionManager connectionManager = Service.getConnectionManager();
if(connectionManager != null) {
connectionManager.onAssetInfoChanged();
}
另一种方法,在我看来,首选方法是首先避免空值。如果您使用 Java 8,您可以使用 Optional
来表示您的 ConnectionManager
可以为空的事实。
最好的方法是确保您的 ConnectionManager
实际上永远不会 null
首先,@Nullable
与可以为空的方法参数有关。相反的是NotNull
,表示必须设置参数。其次,getConnectionManager
的每个调用都由分析器单独处理。这样做
ConnectionManager connManager = Service.getConnectionManager();
if(connManager != null
{
//do your stuff
}
我有一个函数可以 return 空值。所以我使用了 JetBrains 注释并在函数顶部放置了一个 @Nullable
注释。
@Nullable
public static ConnectionManager getConnectionManager() {
return connectionManager;
}
然后,我 运行进行了 Lint 检查。当我使用这个函数时,我发现了 4 个地方,但我没有做任何 null 检查。
之前:
Service.getConnectionManager().onAssetInfoChanged();
之后:
if(Service.getConnectionManager() != null) {
Service.getConnectionManager().onAssetInfoChanged();
}
然后我运行再次检查Lint。令我大吃一惊的是,我仍然得到:
Method invocation '
Service.getConnectionManager().onAssetInfoChanged()
' at line 308 may produce 'java.lang.NullPointerException
'.
我做错了什么?这是 Lint 检查器中的错误吗?
检查员并没有完全错。在这种情况下,您可能会有一个 NullPointerException
:因为您每次都在调用 Service.getConnectionManager()
,所以我们无法绝对确定它不会 return null
第二次,即使不是第一次:getter 的逻辑可能比 return ...
更复杂,或者变量可能已在两个方法之间同时设置为 null
来电。
因此,您可以将代码重构为:
ConnectionManager manager = Service.getConnectionManager();
if (manager != null) {
manager.onAssetInfoChanged();
}
假设getConnectionManager()
的return类型是ConnectionManager
类型的对象。有了这个,就不可能在该行上有一个 NullPointerException
。
问题是您调用了 Service.getConnectionManager()
两次。在您实际使用它的第二次调用时,Lint 必须假设它现在可以为空。解决这个问题的一种方法是使用这样的局部变量:
ConnectionManager connectionManager = Service.getConnectionManager();
if(connectionManager != null) {
connectionManager.onAssetInfoChanged();
}
另一种方法,在我看来,首选方法是首先避免空值。如果您使用 Java 8,您可以使用 Optional
来表示您的 ConnectionManager
可以为空的事实。
最好的方法是确保您的 ConnectionManager
实际上永远不会 null
首先,@Nullable
与可以为空的方法参数有关。相反的是NotNull
,表示必须设置参数。其次,getConnectionManager
的每个调用都由分析器单独处理。这样做
ConnectionManager connManager = Service.getConnectionManager();
if(connManager != null
{
//do your stuff
}