简体   繁体   中英

Using both @Nonnull and Preconditions.checkNotNull(…)

Does it make sense to have a parameter annotated with @Nonnull and later check the same with Preconditions.checkNotNull() ?

What is the difference between them? As far as I understand, using @Nonnull will just specify a contract but will not check further unless you tell it so in your IDE. Is this correct?

The difference is between specification and implementation. @NonNull gives the specification of the routine, and Preconditions.checkNotNull() gives one way to validate the routine.

@NonNull specifies a contract on a formal parameter: the method should never be called with null as the corresponding actual argument.

There are multiple ways to validate such a specification.

  • You can perform run-time checking with an assert statement or, equivalently, Preconditions.checkNotNull() . This will dynamically find violations of the contract at run time, and crash the program. This makes your code easier to debug by giving an earlier warning message, but it doesn't improve code quality.

  • You can perform static checking at compile time using an IDE or other tool. If you use a sound tool, you get a guarantee that no possible execution will violate the specification and crash the program.

You need a specification of your method to document how it is supposed to be used. You might as well write that using @NonNull annotations rather than in English as Javadoc, because @NonNull is concise and machine-readable. So, you should write @NonNull annotations.

It's optional, but useful, to validate the correctness of your specification. Doing validation using both run-time checking and static checking is a belt-and-suspenders approach. It uses two different techniques to validate the specification. Doing run-time checking is a good idea if you use an unsound static checking tool such as FindBugs, since even if FindBugs doesn't issue any warnings, there still might be nullness errors in your code. If you use a sound tool such as the Nullness Checker of the Checker Framework , then the run-time checks are extraneous. They don't hurt much, though: just a little bit of code clutter and a little bit of run-time overhead.

(Note that it is possible for the specification to require a particular exception to be thrown if a null value is passed as an argument. This would require the method body to contain code such as Preconditions.checkNotNull() even if you have already proved that your program never passes null. A specification that dictates the exact exception thrown isn't particularly useful to client code. The client really only wants to know in which circumstances the call will succeed, and the client is unlikely to have a catch block specifically for NullPointerException . Thus, the main information the client needs in the specification is that null is an illegal value.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM