Reputation: 1059
So I just drilled into my colleague that he should not be doing as the title states. But I fought so strongly for my stance that I want to make sure that I am actually right (the worst thing I want to do is enforce an incorrect opinion on someone else).
So basically I'm trying to verify that the following is indeed bad practice:
public void methodA(@Nullable String value) {
if (value == null) throw new IllegalArgumentException();
...
}
His argument was that @Nullable
simply states that you can pass a null
in here, but it doesn't guarantee that the result of doing so will be "nice".
Whereas my argument is that doing so breaks the contract that @Nullable
implies that a null
value will be properly handled and not treated as exceptional.
The problem is I can't find any documentation actually verifying my claim.
Ultimately I was able to convince him of my stance, but now I'm concerned that perhaps I was wrong.
Ah, I am missing some context here. So we are using @NonNullApi
from Spring, which by default puts a @Nonnull
on all the params. So if you want to support a null param, you need to override this with a @Nullable
annotation.
Upvotes: 2
Views: 1826
Reputation: 8137
The Checker Framework manual, section "Annotations indicate non-exceptional behavior", supports your point of view. It states:
You should use annotations to specify normal behavior. The annotations indicate all the values that you want to flow to a reference — not every value that might possibly flow there if your program has a bug.
Under your colleague's reasoning:
His argument was that
@Nullable
simply states that you can pass anull
in here, but it doesn't guarantee that the result of doing so will be "nice".
every reference type could be annotated as @Nullable
, and thus @Nullable
would have no meaning.
Upvotes: 3
Reputation: 272760
The problem is I can't find any documentation actually verifying my claim.
Here's some documentation from the JetBrains Annotations library:
An element annotated with
Nullable
claimsnull
value is perfectly valid to return (for methods), pass to (parameters) or hold in (local variables and fields).
An element annotated with
NotNull
claimsnull
value is forbidden to return (for methods), pass to (parameters) and hold (local variables and fields).
I would say a contract such as "I will definitely throw an exception if you pass a null to this parameter!" would make null a "forbidden" value to pass to that parameter. You should use @NotNull
(or similar) to annotate it instead. It's certainly not a "perfectly valid" value to pass to that parameter.
Of course, your colleague could still argue that since passing null
compiles, it's "perfectly valid" :) but that's just sophistry IMO.
I understand that you are using Spring's annotations, but the wordings in Spring's documentation isn't as strong as the JetBrains' ones, which is why I chose the latter to make a stronger argument. Hopefully you would agree that both pairs of annotations are designed to solve the same problems, and have the same semantics. It would be absurd to have a situation where you should mark something as org.springframework.lang.Nonnull
, but not org.jetbrains.annotations.NotNull
.
Upvotes: 4