Reputation: 4340
I have a function that could return a null value. So I used JetBrains annotation and put a @Nullable
annotation on top of the function.
@Nullable
public static ConnectionManager getConnectionManager() {
return connectionManager;
}
Then, I runned a Lint inspection. I found 4 places when I use this function and I wasn't doing any null check.
Before:
Service.getConnectionManager().onAssetInfoChanged();
After:
if(Service.getConnectionManager() != null) {
Service.getConnectionManager().onAssetInfoChanged();
}
Then I run the Lint inspection again. To my big surprise, I'm still getting:
Method invocation '
Service.getConnectionManager().onAssetInfoChanged()
' at line 308 may produce 'java.lang.NullPointerException
'.
What am I doing wrong? Is this a bug in the Lint inspector?
Upvotes: 3
Views: 1304
Reputation: 5049
First of all, the @Nullable
is related to method parameters that can be null. The opposite is NotNull
which means that the parameter must be set. And secondly, each call of getConnectionManager
is treated by the analyzer separately. Do it like this
ConnectionManager connManager = Service.getConnectionManager();
if(connManager != null
{
//do your stuff
}
Upvotes: 1
Reputation: 21184
The problem is that you're calling Service.getConnectionManager()
twice. On the second invocation when you actually use it Lint has to make the assumption it could now be null. One way to solve this is to use a local variable like this:
ConnectionManager connectionManager = Service.getConnectionManager();
if(connectionManager != null) {
connectionManager.onAssetInfoChanged();
}
An alternative, and in my opinion preferred approach would be to avoid the null in the first place. If you're using Java 8 you can use an Optional
to represent the fact your ConnectionManager
can be null.
The best approach would be to ensure your ConnectionManager
is actually never null
Upvotes: 3
Reputation: 137064
The inspector is not completely wrong. It is possible that you could have a NullPointerException
in this case: since you are calling Service.getConnectionManager()
each time, there's no way we can be absolutely sure that it won't return null
the second time even though it did not the first time: the getter could have a more complicated logic than return ...
or the variable may have been set to null
concurrently between the two method calls.
As such, you could refactor your code to:
ConnectionManager manager = Service.getConnectionManager();
if (manager != null) {
manager.onAssetInfoChanged();
}
assuming that the return type of getConnectionManager()
is an object of type ConnectionManager
. With this, it is impossible to have a NullPointerException
on that line.
Upvotes: 5