Would it be a good idea if compiler resolved nulls when Optional<Object> is expected as argument?
java, java-8, nullable
Solution
There was a HUGE discussion of `Optional` on all the various Java mailing lists, comprising hundreds of messages. Do a web search for
site:mail.openjdk.java.net optional
and you'll get links to lots of them. Of course, I can't even hope to summarize all the issues that were raised. There was a lot of controversy, and there was quite a breadth of opinion about how much "optionality" should be added to the platform. Some people thought that a library solution shouldn't be added at all; some people thought that a library solution was useless without language support; some people thought that a library solution was OK, but there was an enormous amount of quibbling about what should be in it; and so forth. See this message from Brian Goetz on the lambda-dev mailing list for a bit of perspective.
One pragmatic decision made by the lambda team was that any optional-like feature couldn't involve any language changes. The language and compiler team already had its hands full with lambda and default methods. These of course were the main priorities. Practically speaking, the choices were either to add `Optional` as a library class or not at all.
Certainly people were aware of other languages' type systems that support option types. This would be a big change to Java's type system. The fact is that for most of the past 20 years, reference types have been nullable, and there's been a single, untyped `null` value. Changing this is a massive undertaking. It might not even be possible to do this in a compatible way. I'm not an expert in this area, but most such discussions have tended to go off into the weeds pretty quickly.
A smaller change that might be more tractable (also mentioned by Marko Topolnik) is to consider the relationship between reference types and `Optional` as one of boxing, and then bring in the support for autoboxing/autounboxing that's already in the language.
Already this is somewhat problematic. When auto(un)boxing was added in Java 5, it made a large number of cases much nicer, but it added a lot of rough edges to the language. For example, with auto-unboxing, one can now use `<` and `>` to compare the values of boxed `Integer` objects. Unfortunately, using `==` still compares references instead of values! Boxing also made overload resolution more complicated; it's one of the most complicated areas of the language today.
Now let's consider auto(un)boxing between reference types and `Optional` types. This would let you do:
Optional<String> os1 = "foo";
Optional<String> os2 = null;
In this code, `os1` would end up as a boxed string value, and `os2` would end up as an empty Optional. So far, so good. Now the reverse:
String s1 = os1;
String s2 = os2;
Now `s1` would get the unboxed string `"foo"`, and `s2` would be unboxed to `null`, I guess. But the point of `Optional` was to make such unboxing explicit, so that programmers would be confronted with a decision about what to do with an empty `Optional` instead of having it just turn into `null`.
Hmmm, so maybe let's just do autoboxing of `Optional` but not autounboxing. Let's return to the OP's use case:
public static void main(String[] args) {
test(null);
}
public static void test(Optional<Object> optional) {
System.out.println(optional.orElse(new DefaultObject()));
}
If you really want to use `Optional`, you can manually box it one line:
public static void test(Object arg) {
Optional<Object> optional = Optional.ofNullable(arg);
System.out.println(optional.orElse(new DefaultObject()));
}
Obviously it might be nicer if you didn't have to write this, but it would take an enormous amount of language/compiler work, and compatibility risk, to save this line of code. Is it really worth it?
What seems to be going on is that this would allow the caller to pass `null` in order to have some specific meaning to the callee, such as "use the default object" instead. In small examples this seems fine, but in general, loading semantics onto `null` increasingly seems like a bad idea. So this is an additional reason not to add specific language support for boxing of `null`. The `Optional.ofNullable()` method mainly is there to bridge the gap between code that uses `null` and code that uses `Optional`.
Problem
That would be so obviously useful that I am starting to think I am missing a rationale to avoid it, since I am sure Oracle would have made it that way. It would be the most valuable feature on Optional for me. ``` public class TestOptionals{ public static void main(String[] args) { test(null); } public static void test(Optional<Object> optional){ System.out.println(optional.orElse(new DefaultObject())); } } ``` (This throws a NullPointerException) Without that feature I see too verbose using Optional for the argument. I prefer a simple `Object optional` signature and checking it by `if (null = optional)` that creating the object Optional for comparing later. It is not valuable if that doesn't help you checking the null