Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Would it be a good idea if compiler resolved nulls when Optional<Object> is expected as argument?

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

like image 220
Whimusical Avatar asked Feb 22 '15 20:02

Whimusical


People also ask

Why is Optional better for null handling?

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.

What happens when Optional is null?

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 .

Should I use Optional or null?

A variable whose type is Optional should never itself be null ; it should always point to an Optional instance.”

Can you do Optional of null?

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 .


1 Answers

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.

like image 52
Stuart Marks Avatar answered Oct 25 '22 16:10

Stuart Marks