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
In a nutshell, the Optional class includes methods to explicitly deal with the cases where a value is present or absent. However, the advantage compared to null references is that the Optional class forces you to think about the case when the value is not present.
Optional Class is a container for an object that may contains null . With this Optional class, we can semantically told clients that a function they will use may return a null value that lead into NullPointerException .
A variable whose type is Optional should never itself be null ; it should always point to an Optional instance.”
An empty optional is the main way to avoid the Null Pointer Exception when using the Optional API. In Optional 's flow, a null will be transformed into an empty Optional . The empty Optional won't be processed any further. This is how we can avoid a NullPointerException when using Optional .
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With