I decided to edit my question, after seeing that 1 year after, I've changed how I work with nulls:
- I don't use Eclipse builtin null checks, because I found it rather primitive (and perhaps a little tricky to understand)
- I use
@Nullable
to tell a value can be null. After all, there should be less null-values than non-null values. - I'm using Java 8 and I tend to use
Optional
, thus allowing the following:Optional.ofNullable(value).orElseGet(() -> 1);
. It does not beat the?:
and?.
operator of Groovy, but Optional give some nice tool likemap
,filter
, and so on.
And, as for my code:
constructors checks for nulls using
Objects.requireNonNull
, like this:public Foobar(String a) { this.a = Objects.requireNonNull(a, "a"); }
methods checks for nulls using
Preconditions.checkNotNull
from Guava framework whenever I use it in my projects orObjects.requireNonNull
:public void foobar(String a) { Preconditions.checkNotNull(a, "a"); }
Using the one or the other depends on if I reuse the value.
I don't check for method parameters every time, but rather mostly in the public
methods. The idea is not to replace the default runtime check that throws NullPointerException
more efficiently than I can do.
I am currently using @Nonnull
or @Nullable
annotation on all my parameters, fields, method result (return), but I'm wondering what is truly the best :
- How could I tell that my field and method result are non null by default ? (the
@ParameterAreNonnullByDefault
does not work for them). I'd like a portable way (I've read here that I could create my own annotations, with specific names, and that would work for findbugs) - If I annotate package
com.foobar
with@ParameterAreNonnullByDefault
, does it apply tocom.foobar.example
as well ? - Should I check every parameters (I am currently checking constructor parameters) when annotated by
@Nonnull
?
Also, since Eclipse 3.8, there is annotation based null checks. But I have problem with some "simple" case :
@ParameterAreNonnullByDefault
class Foobar<E extends Throwable> {
@Nullable private Constructor<E> one;
@Nullable private Constructor<E> two;
public Foobar(Constructor<E> one, @Nullable Constructor<E> two) {
this.one = Objects.requireNonNull(one, "one");
this.two = two;
}
// don't care about exceptions.
public E getInstance(String msg, Throwable t) {
if (null == two) {
return (E)one.newInstance(msg).initCause(t);
}
return two.newInstance(msg, t);
}
}
Why is telling me that two is nullable at that position, and why he is warning me about potential null access to two ?