Won't those methods still throw an exception if the object is null though? (Honest question, I have not done much Java since Optional was added and was under the impression that it didn't support implementing methods that wouldn't throw exceptions on null like Go can do with nil)
No, and I think you're misunderstanding how Java optionals work. They're just like any ML-type language's option type - a box which can either have something or nothing.
You choose if you want an exception. Map will only run if the optional contains a non-null value, so it won't throw. orElse will safely give you a value if the optional contains a null, so it won't throw either. The only time you throw is when you use orElseThrow, but that's in the name and you know what you're doing.
Ex.
Optional<Integer> x = Optional.ofNullable(null);
// This won't throw!
x.map(i -> i + 1);
// This won't throw either, and safeValue will *definitely* be an int!
int safeValue = x.orElse(5);
// This *will* throw, but you specify what to throw
x.orElseThrow(() -> new RuntimeException())
These three methods cover nearly everything I did with options in OCaml as well, so I think that's about everything you need.
Right, but what about `Optional<Integer> x = null`? Is there any static check to make sure this can't happen, or is it something you have to just avoid? I can imagine someone might accidentally return `null` instead of `Optional.ofNullable(null)` in a method that returns an Optional, but maybe in practice catching this with a lint is enough.
> Is there any static check to make sure this can't happen, or is it something you have to just avoid? I can imagine someone might accidentally return `null` instead of `Optional.ofNullable(null)
The latter. Java's Optionals are half-baked and don't provide as much safety as you'd think because it's easy for a `null` value to slip in. Notice how they used `Optional.ofNullable` — a common footgun is using `Optional.of(value)`, which throws a NullPointerException if `value` is null[1].
This is true, but I think half-baked safety is way better than no safety, and in practice I've found that it's actually pretty difficult for a null to slip in, because that only realistically happens when you're directly assigning values. Library code that returns optionals has never caused any issues IME, and custom code that returns optionals is super easy to review because there's only one good way to make an optional - ofNullable.
It’s just something you have to avoid. It’s not hard to avoid though, unless you are doing bizarre and non idiomatic things with Optional. I have never actually seen a NullPointerException resulting from a null Optional, in my code or my coworkers’, and I’ve been writing Java since their inception.