4 ms·
NPEs are a red herring. My immediate read on people who complain about NPEs is that they haven't done any enterprise Java development. Let's say you have the p
by legerdemain 6y ago
NPEs are a red herring. My immediate read on people who complain about NPEs is that they haven't done any enterprise Java development.
Let's say you have the potential for some reference to be null. And you cleverly wrap it in an Optional or add some @NotNull annotation to it. Great, now how do you handle the null? Maybe it's some query result set that unexpectedly contains zero results or an empty list of live service shards. What do you do to recover? Print an error to the application log and continue running in a corrupted state? Is that really an improvement?
Bugs don't get fixed by adding Optional everywhere or "null coalescing" or whatever, they get fixed by actually understanding how the bug arises during operation. It's a bug in the mental model of how the application works, not at the syntactic level of null references.
- fiddlerwoaroof 6y agoI agree, but I think the benefit of things like Optional is a bit different: it’s not really about eliminating NPE-type bugs, but limiting the scope in which they can occur. If you use them consistently, you only have to check the behavior of places where the optional is unwrapped, and you push those places upwards towards the entry-point rather than weaving null-checks into your business logic. All that being said, the complaints about NPEs have always felt to me like focus on symptoms (null references) rather than the underlying causes (badly-designed application code)
- imoverclocked 6y agoYup, NPEs are not caused in the location that they occur. They are caused by the part of the code that inserts a null where it doesn't belong/isn't expected. This means that getting rid of NPEs requires detailed enforcement across module/method/interface/etc boundaries. If something is labelled @Nonnull (or @NotNull, depending on the annotations used) then it should never be allowed to be null. The issue arises when there is no enforcement of this paradigm at the compiler level. Similar languages (Kotlin/Swift/...) with the benefit of Java in hindsight, can track nullability as a core feature. Java requires a plugin to track+enforce nullability for backward compatibility reasons. errorprone is a Java compiler plugin to add extra sanity checks that the base compiler doesn't/can't provide. NullAway is an errorprone plugin and has been shown [1] to get rid of NPEs. In my experience, anyone who thinks NPEs are unavoidable or even a wanted feature has not sufficiently learned about nullability as a language/type system feature for type systems that allow null values. NullAway isn't the only game in town (for Java) but it's the simplest and easiest model to adopt for a large body of developers that don't necessarily want to think hard about null values and complex type interactions. Finally, I'm speaking from first hand experience of wrangling a large Java codebase with many developers. The mental model of the code is far too complex to hold in any one head. Even just the mental model of nullability is too complex to hold in a single head. The good news is that this is the kind of problem a compiler can excel at... and that a PR check can leverage. [1] https://arxiv.org/pdf/1907.02127.pdf https://arxiv.org/pdf/1907.02127.pdf
- imoverclocked 6y agoOne quick clarification, NullAway inverts the check to enforce, "if something can be null, it needs to be labelled @Nullable" ... it doesn't care at all about @Nonnull annotations. This means that potentially null values are traced accurately through your codebase with @Nullable annotations.
- legerdemain 6y agoThanks, this narrative makes sense to me! I'm a little sad never to have worked on a commercial Java codebase that showed this degree of discipline, though.