Kotlin: Mengenal Null Safety

Null safety merupakan fitur andalan yang ada di bahasa Kotlin. Fitur ini memungkinkan kita menghindari Null Pointer Exception jika kita bisa menggunakannya dengan tepat.

Tipe Data Nullable

Pada Kotlin, kita tidak bisa mengisi variabel dengan null kepada sembarang variabel. Hanya variabel khusus yang dapat diisi null. Contohnya seperti ini:

val nama: String = null

Maka kode tidak bisa dikompilasi dengan kesalahan yang menyatakan bahwa variabel nama tidak bisa diisi null. Lalu bagaimana cara mengisi suatu variabel dengan null ?.

Pada Kotlin, tipe data dikelompokkan menjadi dua kelompok berdasarkan bisa tidaknya variabelnya diisi null.

Kelompok pertama adalah Tipe Data Non-Nullable (tidak bisa null), variabel dengan tipe data ini tidak bisa diisi null. Tipe data String merupakan contoh dari tipe data kelompok ini. Tipe data apa pun yang tidak bertanda ? masuk dalam kelompok ini.

Kelompok kedua adalah Tipe Data Nullable (bisa null), variabel dengan tipe data ini bisa diisi null. Tipe data apa pun yang diberi akhiran ? masuk ke dalam kelompok ini. Contohnya seperti: String?, Int?, dsb.

Kode di atas agar tidak error, kita harus mengubah tipe data variabel nama menjadi Nullable. Kodenya berubah menjadi seperti berikut:

val nama: String? = null

Operasi pada Tipe Data Nullable

Operasi pada tipe data Nullable tidak bisa dilakukan secara langsung, karena variabel bisa berisi null. Kotlin akan menghindari NullPointerException. Jadi dibutuhkan operator khusus saat melakukan operasi pada tipe data Nullable. Dengan begitu, kita akan lebih berhati-hati saat menulis kode dan kita bisa dengan mudah melihat bahwa suatu kode bisa menghasilkan NullPointerException atau tidak berdasarkan operator yang digunakan.

Safe Call

Untuk mengakses properti dari variabel Nullable, kita tidak bisa melakukannya secara langsung seperti ini:

val nama: String? = null
println(nama.length)

Kode tersebut tidak bisa dikompilasi, karena kita mengakses properti variabel Nullable secara langsung. Untuk mengakses propertinya kita bisa menggunakan operator Safe call dengan mengubah . menjadi ?..

val nama: String? = null
println(nama?.length)

Lalu apa yang sebenarnya dilakukan operator di atas?. Jika variabel nama berisi null maka operator tersebut akan menghasilkan nilai null sedangkan jika variabel tersebut tidak berisi null maka operator tersebut akan memberikan nilai properti length.

var nama: String? = null
println(nama?.length) // null
nama = "Levi"
println(nama?.length) // 4
nama = null
println(nama?.length) // null

Saat menggunakan Safe call, tipe data yang dihasilkan berupa Nullable. Misal, tipe data properti length adalah Int, tapi karena menggunakan Safe call tipe data yang dihasilkan nama?.length adalah Int?

Safe call juga dapat digunakan untuk memanggil fungsi anggota objek. Contohnya:

var nama: String? = null
println(nama?.trim()) // null
nama = "  Levi  "
println(nama?.trim()) // Levi
nama = null
println(nama?.trim()) // null

Keluaran fungsi trim() bertipe data String, tapi karena menggunakan Safe call keluaran nama?.trim() bertipe data String?.

Bang Operator

Bang Operator (!!) adalah solusi lain untuk mengakses properti variabel nullable.

var nama: String? = "Levi"
println(nama!!.length) // 4
nama = null
println(nama!!.length) // Error java.lang.NullPointerException

Jika variabel nama tidak berisi null, maka operator akan memberikan nilai propertinya. Sedangkan jika nilai variabelnya null, maka akan dikeluarkan error saat kode dijalankan. Berbeda dengan Safe call, operator ini tidak mengubah tipe data yang dihasilkan. Misal nama.length bertipe Int, saat menggunakan Bang Operator, tipe data nama!!.length tetap Int.

Bang operator juga bisa digunakan untuk memanggil fungsi anggota kelas. Contoh:

var nama: String? = "  Levi  "
println(nama!!.trim()) // Levi
nama = null
println(nama!!.trim()) // Error java.lang.NullPointerException

Keluaran fungsi nama!!.trim() tetap String.

Elvis Operator

Pada suatu saat, mungkin kita menginginkan untuk menggunakan nilai default jika suatu variabel berisi null. Kita dapat menggunakan Elvis Operator (?:) seperti berikut:

var nama: String? = "Levi"
var namaNonNullable: String = nama ?: ""

Saat nama tidak null, maka nama digunakan sebagai nilai namaNonNullable. Jika nama null, maka digunakan nilai default yaitu "".