Last week I was working on a code base which had been partially converted from Java to Kotlin. The converted Java code base was making extensive use of
java.util.Optional. The use of Optional might be helpful in situations where you want to be very explicit about the fact that a function or variable might be empty (null), to avoid
But do you still need this in Kotlin? Especially since one of the nice features of Kotlin is that null safety is build into the language. Let’s look at an example. Below the simplified version of the real Java code:
The goal of Optional in the method
public Optional<Order> findOrderById(Long id) is to make clear what the possible values returned from this function might be. Using an Optional we might expect an Order or nothing (null). If we were to convert the code to Kotlin, the code would look like this:
But do we really need the Optional in the Kotlin version? Kotlin has null safety build into the language right? In Kotlin the usage of Optional would in my opinion be Optional 🙂 How rewrite the code? Look at the following fragment:
The returned value from
fun findOrderById(id: Long): Order? is already very clear (to me), the method either returns an Order or null, this is exactly what the question mark behind a type in Kotlin means. Kotlin forces you to be very explicit about the nullability, which is in my opinion a good thing, especially since the compiler enforces this.
Now if we would be invoking this function, let’s compare the Java and the Kotlin version in the case that we want to handle the result if it exists.
In the Java version we would need to handle the Optional object. We can use
Optional.ifPresent with a lambda expression to handle the situation where there is a result.
In the Kotlin version we can handle the result using the safe call operator
?. and then execute the
run function when there is a non null value. One of the nice things is that Kotlin gives us way more flexibility in what we want to do when the value is not null. We could use
apply if we want to return the Order type, or use
let if we want to return any other type from the function.
You do need to be aware that when using the order object that you are applying the safe call operator consistently, otherwise the compiler will gently remind you about this 😉
What you miss out on is
Optional.orElseThrow when ditching
java.util.Optional, but in Kotlin we could solve this easily using the elvis operator.
Combining this with
apply gives us just way more flexibility.
Do we need Optionals in Kotlin? Personally I don’t miss them and frankly don’t use them in my Kotlin code base anymore. For Java applications it makes more sense if you want to be clear about a variable or return value from a function invocation, but in Kotlin we get this built into the language for free.
What do you think?