Learning Kotlin: Nullable Types

Note * The code being referenced. * This is the 8th post in a multipart series. If you want to read more, see our series index.

The next Koan looks at how Kotlin handles nulls, and it does it wonderfully—Null is explicitly opt-in. For example, in C#, you can assign null to a string variable, but in Kotlin, unless you say you want to support nulls—by adding a trailing question mark to the class—you cannot. Their example in this Koan is a nice example:

fun test() {
    val s: String = "this variable cannot store null references"
    val q: String? = null
    if (q != null)
        q.length // you have to check to dereference
    val i: Int? = q?.length // null
    val j: Int = q?.length ?: 0 // 0
}

Let’s dig into the Koan, where we’re given the following Java code:

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);
}

And we need to rewrite it using Kotlin’s nullable language features, which looks like this:

fun sendMessageToClient(client: Client?, message: String?, mailer: Mailer) {
    val email = client?.personalInfo?.email
    if (email == null || message == null) return
    mailer.sendMessage(email, message)
}

The big changes from Java:

  1. The @NotNull attribute for mailer is no longer needed.
  2. The @Nullable attribute for the other parameters becomes the question mark.
  3. We no longer pre-check client before calling personalInfo, as you can use the null-safe operator ?. to ensure we only attempt the operation if the object isn’t null.
  4. Unfortunately, the null-safe operator in Kotlin doesn’t support calling methods on null objects as C# currently does with its Elvis operator.