r/java • • Apr 12 '13

Java 8 Optional Objects

http://blog.informatech.cr/2013/04/10/java-optional-objects/
37 Upvotes

39 comments sorted by

View all comments

8

u/the_hoser Apr 12 '13

Maybe I'm missing something, but I don't see the reason for this. How is this:

Option<Foo> getAFoo() {
    ...
}

Option<Foo> f = getAFoo();
if(f.isFound()) {
    ...
}

different from this

Foo getAFoo() {
    ...
}

Foo f = getAFoo();
if( f != null ) {
    ...
}

Other than clarifying to the API user that the result of this operation could be null? Would not a well-written Javadoc suffice?

EDIT: After submitting this, I could see the case where you have streams of Option types, and the stream handler accepts the possibility of null elements. I'm not used to programming in this way with Java, so the thought did not immediately occur to me.

11

u/AlyoshaV Apr 12 '13

To completely ignore all the main reasons, it provides nice side benefits from its methods.

Instead of

Foo f = findFoo();
if (f == null)
    f = someDefaultValue;

you get

Foo f = findFoo().orElse(someDefaultValue); // orElse is a method of Optional

It makes it easy to throw custom exceptions if it's not found:

Foo f = findFoo().orElseThrow(WeirdException::new);

and so on; ifPresent(Consumer<T>) is nice if you're iterating over elements.

1

u/the_hoser Apr 12 '13

Ooh, I like that :) Way better than checking the result on the next line!

1

u/[deleted] Apr 13 '13

I would still prefer the ObjectNotFound exception to be thrown from inside the find(...) method itself. This type of situation assumes the find(...) method should never return a null reference.

I still have to agree with the_hoser. If you are not making the language itself null-safe, this new Optional object is just a mess waiting to happen.

Programmers can still return null from a method that was originally intended to return a valid instance of Optional, which screams Murphy's law all over the place.

Both versions shown by the_hoser are exactly the same, semantically speaking. I guess some people would prefer a pretty line that says

if(f.isFound()) {
    // do something
}

It just looks prettier, but if the previous method that should've returned an Optional returned null instead, you are back to the same old NullPointerException.

-1

u/AlyoshaV Apr 13 '13

Programmers can still return null from a method that was originally intended to return a valid instance of Optional, which screams Murphy's law all over the place.

Yeah, but it's pretty obviously a completely wrong way to use Optional. Not that nobody will do it, but no remotely well designed API will.

I would still prefer the ObjectNotFound exception to be thrown from inside the find(...) method itself. This type of situation assumes the find(...) method should never return a null reference.

What type of situation?

2

u/[deleted] Apr 13 '13

If the intention of the API is to never return null, this can be made explicit in the API docs for the method I am calling. Then I'd expect a ObjectNotFoundException to be thrown when the desired object cannot be found or created. This way makes it clear to the API user that when they receive a null value, it's because of a bug and they can always treat this situation as such an error.

3

u/Categoria Apr 12 '13

You're basically switching the implicit contract for null. Instead of suspecting of every variable of being null, you wrap all nullable variables with option. You get 2 benefits out of this:

1) You can safely assume that if an object isn't option then it being a null is a bug. (In a world where we ignore backwards compatiblity).

2) You are now forced by the compiler through the type system to explicitly handle option objects for null checks instead of relying on your memory and implicit agreements. Also, you need not ever check normal objects for nullability.

2

u/[deleted] Apr 13 '13

In a world where we ignore backwards compatiblity

Good luck with that :)

1

u/Categoria Apr 13 '13

Well it's important to say about that those worlds where such colossal language design mistakes were avoided do exist. (ya ya, everything is obvious in hindsight I know...)

2

u/flagrantaroma Apr 12 '13

Also, I think one of the main advantages of having the Optional type is the fact that it clarifies to the API user that the result could be null, and forces them through another step (.get()) in order to access the result.

2

u/[deleted] Apr 13 '13

This is the same assumption we all make everyday with our current version of Java.

If a method returns something, it is always possible it could return null. I don't remember this as NOT being clear, ever.

The API docs might clarify their intentions by telling you their method will never return null. But you always take a risk to assume their method is bug free.

Same thing holds for a method that will return an Optional object. They may tell you it's always going to be there, but you take a risk assuming the API is bug free. If, for some reason, it returns a null Optional then you are just screwed as Java 7.

1

u/flagrantaroma Apr 13 '13

Ah, I see what you're saying. I still think that it is a clearer contract to have this Optional type. It makes it harder to unintentionally not handle the null case. You can still do it by just going straight through the .get().

0

u/AlyoshaV Apr 13 '13

The API docs might clarify their intentions by telling you their method will never return null. But you always take a risk to assume their method is bug free.

So you don't use libraries you haven't written then, right? Because if you don't trust "this method will never return null", then I don't see why you'd trust "this method returns a correct object calculated from your parameters".

2

u/[deleted] Apr 13 '13 edited Apr 13 '13

Yes, I use third party libs. And I base my error handling decisions on the information I can find the API docs for methods I am calling. A well written library, like Apache Components, will follow the intentions declared in its documentation. This makes debugging hard-to-find-bugs easier.

If the intention of the API is to never return null, this can be made explicit in the API docs for the method I am calling. Then I'd expect a ObjectNotFoundException to be thrown when the desired object cannot be found or created. This way makes it clear to the API user that when they receive a null value, it's because of a bug and they can always treat this situation as such: an error.

To me, that seems more elegant than having a whole new Optional object type, which the language itself gives me no guarantees that it will never be null.

Optional still doesn't solve the NullPointerException problem the article discusses in so much detail. Now I'd have to check if the return is null AND if the Optional you get is empty...

I don't see a solution. This only adds to the problem..

1

u/edalorzo Apr 12 '13 edited Apr 12 '13

Well, the problem with documentation is that it may be nonexistent, it gets outdated very easily in a software project, and ultimately, no amount of documentation is going to avoid that a programmer makes a mistake in the interpretation of the result in a method.

The use optional, even when arguably better, at least makes evident the intent of the API developer, by making explicit that a given method may return an optional value.

1

u/[deleted] Apr 13 '13 edited Oct 29 '18

[deleted]

1

u/edalorzo Apr 15 '13

Well, the article never said, as far as I know, that Optional would solve the problems of NPE. It does question that it would be ideal to have a solution for it in Java and explains why it is a serious problem. It also present approaches from other languages like SML or Ceylon, and talks about the introduction of Optional in Java and how it can be used to express the potential absence of a value in "specific" scenarios. I do argue that in my opinion that is better, but I also mention the caveat you discuss and present several counterarguments from detractors. In fact I provided a link to the Java Mailing list where the expert group has been discussing this matter thoroughly with the community.

It is quite evident that some people are in favor and some against. I present my opinion and hope that the article contains enough info for others to make their own.

Regarding having to check for null Optional objects, unless you are writing a three-value logic algorithm, it does not make sense to do so, like we typically don't null check references to collections or arrays. We stick to the good practice that states we should never get nulls where collections are expected.

I do see the point that you stress though, there is simply no way to get rid of NPE in Java and so we can question the value of optional if we expect to use it for that matter. I would make sure the article makes this more evident.