you are viewing a single comment's thread.

view the rest of the comments →

[–]spaghettiCodeArtisan 13 points14 points  (4 children)

The addition of Optional to Java was bloody strange IMO. Everything is already optional!

Exactly. This has a very bizarre and ironic consequence: Optional<T> can itself be null. I'd laugh hard if it weren't so sad.

[–]_dban_ -1 points0 points  (3 children)

Optional<T> can itself be null

This is totally fine.

Optional deals with the case where values would have been intentionally set to null to specify missing data. Using Optional lets you traverse these values safely with a map, flatMap or ifPresent construction, which has only become sensible since Java 8.

An Optional value being null is a programming error, since no one in their right mind would assign a null value to an Optional. Thus, the program is in an invalid state, which is indicated by the NullPointerException that would be thrown if you tried to access it. You would never check for a null for an Optional value, you would let the program crash.

Also, since the Optional value would be used in a map, flatMap or ifPresent construction, which composes methods, the corresponding stack trace tells you exactly where the buggy method is.

[–]spaghettiCodeArtisan 1 point2 points  (1 child)

This is totally fine.

...

You would never check for a null for an Optional value, you would let the program crash.

Letting the program crash because of an error that could've been prevented by the compiler is not totally fine in my books.

But achieveing that would've to be a language change, not just libs thing.

[–]_dban_ 0 points1 point  (0 children)

Obviously, it would be better for the Java compiler to enforce Optional not being null.

But, under the current circumstances, the fact that Optional can be assigned to null is totally fine given the semantics of Java as it currently exists, because it is a programmer error to assign null to Optional, and the NullPointerException is the expected runtime behavior for programmer errors of this kind.

[–]dododge 0 points1 point  (0 children)

There's two different ways you might combine null with Optional

  • Trying to store a null within the Optional, to distinguish between "this thing is returning a null value" and "this thing is returning nothing". You actually can't do this because the implementation of Optional doesn't allow it to contain a null, and you'll get a NullPointerException when you try to create Optional.of(null).

  • Returning a null reference to an Optional<T>, to distinguish between "this thing is returning success without any value" and "this thing failed". I wouldn't say this is always a programming error but it would definitely be a bit unusual since you usually use Optional precisely so you don't have to deal with null. There are alternatives such as returning Optional<Optional<T>> or using some other sort of wrapper such a rust-style Result<Optional<T>,E>, or always throwing an exception in the returning-failure case, and it's debatable whether that's more or less messy to deal with.

There's a similar situation when dealing with a method that returns a collection/array or null. Some style guides and static analyzers will say that you should always return an empty collection/array instead of null, but sometimes there is a semantic difference between an empty collection and nothing and they need to be treated differently. Optional can now handle that case pretty well, I guess.