Hacker News new | ask | show | jobs
by unscaled 688 days ago
Unfortunately for Java, Optional in Java is a bit of mess now, until you'll be able to specify nullability. Since T in Optional<T> has unspecified nullability, calling Optional.of() is still unsafe and can result in an NPE, if the argument is null.

What's even worse is that APIs that return Optional<T> can just return null for the Optional value itself! This a pretty evil thing to do on purpose, but this could still easily happen by mistake. If you want to make code using optionals null-safe you have to go through quite some hoops and check that both that Optional<T> is neither null nor empty.

I hope Java can now change the API of Optional and make it safer. For instance, Optional<T>.of() should require a `T!` argument, while Optional.flatMap() should require that the mapper returns a non-nullable Optional value. Likewise, linters should reject any definition of an Optional that is nullable or has unspecified nullability.

2 comments

>but this could still easily happen by mistake.

I have yet to see this ever happen, despite working in Java shops using Optional heavily since it was included in the JDK. I would guess that this is due to developers using better tooling. IDEs commonly provide warnings when returning null, or when violating a "soft" nullability assertion marked by an annotation. NullPointerExceptions seem fairly rare.

I do remember seeing this happen firsthand, but I don't remember where.

Yes, this is not likely to happen with a good IDE with warnings enabled, and developers not ignoring said warnings. It is even less likely with a strict lint step in your CI/CD which treats all non-suppressed warnings as errors. This should be the standard for every software project in the world.

Unfortunately, for many enterprise scenarios, developers are not encouraged (or even discouraged) to apply these best practices. I'm talking about your typical setting with non-technical management, low-salaried or outsourced developers, tech debt rarely being fixed and the only best practices which exist date back to the 1990s or early 2000s.

Doubly unfortunate is the fact that shops of this type _overwhelmingly_ favor Java. For better or worse, Java is the #1 enterprise language and the COBOL of the 21st century. As such, something that would be a non-issue in Rust (where few developers would dare push to production code that didn't pass cargo clippy with flying colors), becomes a rather big issue in many shops.

While applying practices like treating warnings as errors on a CI server is something that every development team probably should be doing, it’s more a symptom of a generally weak development team than the thing that was holding the team back.

If a company policy mandated that it must be on, it would probably not meaningfully reduce poor code because the team was so poor in the first place, they probably don’t understand the problem it solves, so will just work around the now “error” using the least amount of effort to appease the CI server, while still leaving problems in their wake.

Strong teams regularly and consistently reflect on their processes towards continuously improving, such teams will naturally move to applying such a practice as it will add value.

Weak teams tend to just do what they always did until forced to do something new and even then they do it more cargo cult style than in a way that actually improves the bottom line.

All the value like types, like Optional, are planned to be value classes or value records, when Valhala lands.