I can see that @Nullable
and @Nonnull
annotations could be helpful in preventing NullPointerException
s but they do not propag
Short answer: I guess these annotations are only useful for your IDE to warn you of potentially null pointer errors.
As said in the "Clean Code" book, you should check your public method's parameters and also avoid checking invariants.
Another good tip is never returning null values, but using Null Object Pattern instead.
Since Java 8 new feature Optional you should not use @Nullable or @Notnull in your own code anymore. Take the example below:
public void printValue(@Nullable myValue) {
if (myValue != null) {
System.out.print(myValue);
} else {
System.out.print("I dont have a value");
}
It could be rewritten with:
public void printValue(Optional<String> myValue) {
if (myValue.ifPresent) {
System.out.print(myValue.get());
} else {
System.out.print("I dont have a value");
}
Using an optional forces you to check for null value. In the code above, you can only access the value by calling the get
method.
Another advantage is that the code get more readable. With the addition of Java 9 ifPresentOrElse, the function could even be written as:
public void printValue(Optional<String> myValue) {
myValue.ifPresentOrElse(
v -> System.out.print(v),
() -> System.out.print("I dont have a value"),
)
}
If you use Kotlin, it supports these nullability annotations in its compiler and will prevent you from passing a null to a java method that requires a non-null argument. Event though this question was originally targeted at Java, I mention this Kotlin feature because it is specifically targeted at these Java annotation and the question was "Is there a way to make these annotations more strictly enforced and/or propagate further?" and this feature does make these annotation more strictly enforced.
Java class using @NotNull
annotation
public class MyJavaClazz {
public void foo(@NotNull String myString) {
// will result in an NPE if myString is null
myString.hashCode();
}
}
Kotlin class calling Java class and passing null for the argument annotated with @NotNull
class MyKotlinClazz {
fun foo() {
MyJavaClazz().foo(null)
}
}
Kotlin compiler error enforcing the @NotNull
annotation.
Error:(5, 27) Kotlin: Null can not be a value of a non-null type String
see: http://kotlinlang.org/docs/reference/java-interop.html#nullability-annotations