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:
- The
@NotNullattribute formaileris no longer needed. - The
@Nullableattribute for the other parameters becomes the question mark. - We no longer pre-check
clientbefore callingpersonalInfo, as you can use the null-safe operator?.to ensure we only attempt the operation if the object isn’t null. - Unfortunately, the null-safe operator in Kotlin doesn’t support calling methods on
nullobjects as C# currently does with its Elvis operator.