Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - best way to detect NPE at compile time when not allowed to use @NotNull or @Nullable annotations

I used to use lots of @NotNull/@Nullable annotations to enable IDE to help me find out potential NPE at compile time. However, my new team doesn't allow any use of @NotNull/@Nullable annotations, and nor are custom annotations like those allowed. As a result, I become much more likely to write bugs caused by NPE than before.

I have tried several solutions:

  1. Use Optional<T> in java 8. However, this is not doing well for every case. It's usually not recommended to use Optional<T> as the type of fields or arguments. It's also very frustrating that Optional<T> instance itself could be null. Also, it's difficult to operate control flows inside lambda expressions when calling ifPresent(obj->...)(it's easier in Java 9). And using too many Optional<T>s makes the code a little verbose.(UPDATE: Unfortunately, Optional<T> is also banned from using now)
  2. Make IDE treat every unannotated instance as @Nullable. This solution does help me find out some potential bugs, however, IDE would suggest me to check almost every method invocation, which is really annoying, since many methods are designed intentionally not returning null.
  3. Check every method invocations. This is a viable solution, however it has a severe influence that the possibility of being null would be passed everywhere through method invocations. Under such circumstances, every argument of a method is possible to be null, and when an argument is checked for nullity, the method would usually return a null continuously. Finally, every method is "infected" with the possibility of receiving null arguments and returning null.
  4. Call Objects.requireNonNull() to prevent the problem aforementioned. It slightly reduces the pain of checking null everywhere. However, it provides no guarantee that the caller won't pass a null to the cases when null is not allowed. And once null is passed, the runtime NPE thrown is much more likely to ruin your application.
  5. Switch to kotlin. Of course, it's not allowed:)

Is there other suggestions about detecting NPE at compile time (and save my job)? I think a solution to this problem could be widely used, not only helping myself, since not all teams allow usage of @NotNull/@Nullable annotations and Optional<T>s.

like image 338
ProtossShuttle Avatar asked Aug 25 '17 12:08

ProtossShuttle


2 Answers

Not a definitive answer but a few way to explore:

  • Tools like findBug, PMD , Coverity ... are quite good at this exercice.
  • Check the reason why you cannot use the annotation in your team. Maybe you can make your team change its mind? (There might be a good reason too.)
  • Eclipse IDE is reasonnably good at this exercice. Did you try the options in 'Windows > Preferences > Java > Compiler > Errors/Warnings > Null analysis'?
  • Unit testing. Cover the 'should-not-happen' situation in a few test cases. Code coverage tools (like JaCoCo) might be helpfull as wel.
  • Defensive programming (plain 'if' statement, assertions ...)
  • A mix of the previous items

Hope this helps.

like image 194
Algiz Avatar answered Oct 16 '22 22:10

Algiz


You did not say what IDE you are using but Eclipse and Intellij support external annotations. With them, you can still annotate your code locally and have the IDE provide null analysis.

Intellij Documentation
Eclipse Documentation

like image 30
Faron Avatar answered Oct 16 '22 23:10

Faron