Kotlin mengharuskan variable dideklarasikan dengan ? jika variable tersebut bisa bernilai null:
1 |
var str: String? = null |
Jika hal itu tidak dilakukan, maka tidak akan bisa dicompile, contoh lain yang akan menghasilkan error ketika di-compile:
1 |
var str: String = null |
Type checking and casting.
Misal variable obj dengan type generik A, kemudian kita ingin menguji apakah obj juga merupakan instance type tertentu, maka Kotlin menyediakan operator is? yang ekuivalen dengan instanceof? di Java.
1 2 3 |
fun isString(any: Any): Boolean { return if (any is String) true else false } |
Dari contoh diatas, jika tipe target tidak valid (misal string di-cast sebagai File?), maka akan error ClassCastException? pada saat runtime.
Smart Casts.
Di Java, setelah pengecekan tipe dan ingin menggunakan variable instance sebagai tipe tertentu, maka harus secara explicit di-cast sebagai tipe tersebut:
1 2 3 4 5 6 |
public void printStringLength(Object obj) { if (obj instanceof String) { String str = (String) obj System.out.print(str.length()) } } |
Di Kotlin, compiler sudah bisa mengetahui bahwa setelah pengecekan dan variable merupakan tipe data tertentu, maka reference berikutnya tidak perlu lagi secara explicit di-cast.
1 2 3 4 5 |
fun printStringLength(any: Any) { if (any is String) { println(any.length) } } |
Variable yang bisa digunakan smart casts adalah variable yang tidak berubah ketika pengecekan dan penggunaanya. Jadi field var dan local var yang tertutup dan berubah nilainnya (karena digunakan dalam fungsi anonim sehingga berubah nilai) tidak bisa digunakan dalam smart cast.
Smart cast juga bisa digunakan dalam sisi-kanan operand operasi Boolean jika sisi-kiri operand adalah pengecekan tipe.
1 2 3 |
fun isEmptyString(any: Any): Boolean { return any is String && any.length == 0 } |
Compiler tahu bahwa dalam operasi &&? ekspresi sisi kanan tidak akan dievaluasi kecuali sisi kiri
true?, jadi variabelnya harus berupa string. Oleh karena itu, compiler mengkonversi dan memungkinkan kita mengakses properti length? di sisi kanan.
Begitu pula dengan operasi ||, contoh:
1 2 3 |
fun isNotStringOrEmpty(any: Any): Boolean { return any !is String || any.length == 0 } |
Dalam fungsi diatas, kita menguji apakah variable bukan String?, tapi jika memang variable tersebut String? maka sudah pasti empty string.
Explicit casting
Untuk mengkoversi tipe variable secara eksplisit, kita menggunakan operator as . Seperti halnya di Java, akan error ClassCastException? jika operasi gagal dilakukan.
1 2 3 4 |
fun length(any: Any): Int { val string = any as String return string.length } |
Nilai Null tidak dapat di-cast sebagai tipe data tertentu jika variablenya tidak didefinisikan sebagai nullable. Dari contoh diatas akan error jika parameternya null. Jadi untuk bisa cast variable null, maka variablenya juga harus bisa nullable.
1 |
val string: String? = any as String |
Yang perlu diingat, jika cast gagal akan error ClassCastException , namun jika kita ingin nilai null daripada error, maka kita bisa menggunakan safe cast operator as?
1 2 3 |
val any = "/home/users" val string: String? = any as? String // cast sukses berupa string val file: File? = any as? File // null |