What is the difference between following two code snippets.
public Integer getId(@Nonnull SomeObject obj){
// do some stuff
return id;
}
public In
The difference is that in the first case it's a hint for a compiler and IDE that the argument should not be null, so when you write getId(null)
you'll get an error. But someone may pass null
value in runtime.
As for the second case, it's a kind of defensive programming, when you fail-fast with a precondition that the argument should not be null
.
The two are complementary: @Nonnull
annotation documents the fact that obj
must be non-null, while Objects.requireNonNull
call ensures that obj
is non-null at run-time.
You should combine the two, like this:
public Integer getId(@Nonnull SomeObject obj){
Objects.requireNonNull(SomeObject, "SomeObject is null");
// do some stuff
return id;
}
Relevant documentation on @Nonnull
can be found here:
Optional Type Annotations are not a substitute for runtime validation
Before Type Annotations, the primary location for describing things like nullability or ranges was in the javadoc. With Type annotations, this communication comes into the bytecode in a way for compile-time verification.
Your code should still perform runtime validation.
One of these is an annotation which implements JSR-305, but is meant more for static analysis as opposed to a runtime guard. As I recall it, JSR-305 is a good idea in principle and a lot of things actually leverage it in some way, but it loses a lot of its bark when its utility only ever comes in the form of static analysis.
Case in point: your IDE can leverage this to warn you of situations in which you're passing something you shouldn't, but it can't prevent you from passing null
into this method when you compile.
Objects.requireNonNull
is a runtime enforcement that whatever it's passed will be a non-null reference. The compiler can't enforce this either, but at runtime should you receive a null value, you will get a NullPointerException
upon executing that line of code.
In terms of correctness, using Objects.requireNonNull
is a good idea, but that depends on what your obligation is when running the application. If you must fail on a null value, then using that is fine as it will generate a runtime exception to deal with. If you can't fail on a null value, then using an if
check instead would be better.