What is Java 8 Optional for? How to use it?

Asked

Viewed 2,002 times

3

1 answer

5


Purpose

It’s quite funny because the biggest reason to use it is to avoid exceptions, just in the language that invented abuse in its use :)

When you may have a result or not, the normal way of Java has always been to make an exception when it does not give the result, so a method can take two actions, give a result or deviate the flow in a brutal way, paying a very high price and complicating the flow in many cases. Actually "always" is a bit of an exaggeration because there are many cases that the method returns null or some error code as in indexOf(). I say all this in Why should we avoid returning error codes?.

So since version 8, when the situation is not exceptional, it is normal that a problem happens and a result may not be possible, one of the solutions would be to return a Optional, then you have an error or the result.

With it you can only take the result if it exists and have to test somehow (there are facilitators), do not run the risk of catching an invalid result, and is obliged to check, contrary to the exception that is not required (even if the popular belief is that it is).

Modern languages have preferred this over the exception. Even those that still want exception use virtually as error code.

There is no standard Java, but there are those who use Maybe (a Monad) or Result (informs which error has occurred and not only whether or not it has worked) but other ways to have a result that may or may not exist.

How to use

I think the part about how to use it would be another question, but come on, at least one basic example, to talk about it all would be very broad.

Optional<User> user = findUserById("1234");
if (user.isPresent()) System.out.println("Nome do usuário = " + user.get().getName());

The most functional way to do:

user.ifPresent((user) -> {
    System.out.println("Nome do usuário = " + user.getName());  
})

This method should be something like this (in a very simplified way):

Optional<User> findUserById(string id) {
    var user = database.user.query(id); //pode retornar null
    return Optional.ofNullable(user);
}

I put in the Github for future reference.

When the object cannot be null and wants to indicate that there will be no result can use Optional.empty(), this way the object will have an indicative that there is no result and therefore can not use it.

Before the normal was to return only the null, what could be promptly ignored and give the famous Nullpointerexception. Or I could give a throw that turned into a tragedy (that Java programmers kept saying it didn’t matter, and now they’re changing their minds because the language can do it better - it’s called fanboyism).

It is clear that the indexOf(), or parse() and its resemblances of various objects, and much of the methods that return null should have used this mechanism if it existed before, right?

The use of it becomes even more important when the method does not access an external resource, because a database generate an exception is not the end of the world, although semantically not find the user is something expected and not exceptional, so the exception is not the most appropriate mechanism. A simple validation or calculation is already a huge problem to abuse the exception when it is normal for a failure to occur (it may still be useful to throw an exception when it is something that should not occur, such as a division by zero for example).

Completion

This form is more declarative and less imperative, so it is considered more functional.

Too bad language put this before having types for value in the language, so it’s a class, it’s ugly and inefficient.

I think I can fit more specific questions.

Java practically created the idea of "exclusively" object-oriented language, which was never true, and now, for good, it has adopted a functional style, in part, and the community has embraced it (at least a good part of it, that thinks a little, that follow good references). What saddens me is that C# who hitchhiked in Java, adopted the functional before because "never" sold as OO, and still has reference people in the community who are against the use of this optional result mechanism and prefer the exception (in some countries there is more acceptance, they have better references).

  • I particularly find it very ugly to use isPresent(), does not eliminate the need for a conditional to check internally a != null. I find it more practical to use static methods Optional.of() and Optional.ofNullable combined with get, orElse, orElseGet and orElseThrow

  • Yeah, language never helped much, but it’s an improvement.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.