Kotlin introduces a nullable data type. The idea behind it is to dramatically reduce if not eliminate the NullPointerException. Developers of almost any language have had to fight with some sort of exception that get’s thrown when trying to derefence a null type.
This portion of the Kotlin Koans tutorial has us rewriting the following Java code in Kotlin.
public class JavaCode7 extends JavaCode { public void sendMessageToClient(@Nullable Client client, @Nullable String message, @NotNull Mailer mailer) { if (client == null || message == null) return; PersonalInfo personalInfo = client.getPersonalInfo(); if (personalInfo == null) return; String email = personalInfo.getEmail(); if (email == null) return; mailer.sendMessage(email, message); } }
Readers will see the amount of boilerplate that is in this code. You have three if statements that are dedicated to checking if a reference is null or not.
I do like the @Nullable annotations because it lets me know that these incoming parameters can be null and I need to know to check for a null case. Lombok has a similar @NonNull annotation that does the job of throwing a NullPointerException if the incoming parameters are null.
JDK8 (3rd prior libraries prior to JDK8) did give Java developers an Optional class and JDK7 has the Objects.nonNull method. These classes help with null safety, but at the cost of more boilerplate.
public class Optionals { public void sendMessageToClient(Optional clientOptional, Optional messageOptional, Mailer mailer){ clientOptional.ifPresent(client -> messageOptional.ifPresent(message -> { PersonalInfo personalInfo = client.getPersonalInfo(); if (nonNull(personalInfo) && nonNull(personalInfo.getEmail())){ mailer.sendMessage(personalInfo.getEmail(), message); } })); } }
Kotlin has a ?: operator that helps with dealing with the NullPointerException.
fun sendMessageToClient( client: Client?, message: String?, mailer: Mailer ) { message ?: return val email = client?.personalInfo?.email ?: return mailer.sendMessage(email, message) }
The Kotlin code does the same thing as the Java code but there are a few things to discuss. When Kotlin parameters have a ? operator, that means they can be a null type. Unlike Java, the Kotlin compiler forces you to address the null case in such variables. I feel this is a super helpful feature because it’s easy to overlook a null case without compiler checks.
By the time we get to mail.sendMessage
the variables email and message have to have values or the code will not compile. This is because the previous two lines force us to check for null values and if they are null, return from the function.
You can click here to see Part 7