Property adalah cara Kotlin merepresentasikan data milik object. Berbeda dengan Java yang memisahkan field dan method getter/setter, Kotlin menyatukan keduanya menjadi satu konsep bernama property. Dari sisi pemanggil, akses buku.harga terlihat seperti akses field langsung, namun di balik layar kompilator dapat memanggil getter atau setter yang kita sesuaikan. Pada chapter ini kita akan membedah property var dan val, memperkenalkan backing field dengan keyword field, dan membuka jalan untuk lateinit var yang ditujukan untuk property non-null yang diisi belakangan.
Property var dan val #
Property dideklarasikan dengan dua keyword: var untuk property mutable dan val untuk property read-only. Property val hanya dapat ditugaskan satu kali, biasanya saat inisialisasi. Property var dapat ditugaskan ulang berkali-kali. Kedua jenis property wajib diinisialisasi saat deklarasi atau di dalam constructor, kecuali bila menggunakan modifier khusus seperti lateinit.
class Buku(val judul: String, var harga: Int)Pada contoh di atas, judul bersifat read-only dan harga bersifat mutable. Pemanggil dapat membaca buku.judul tetapi tidak dapat menugaskannya ulang, sedangkan buku.harga = 80000 diizinkan.
Backing Field dan Keyword field #
Setiap property Kotlin memiliki penyimpanan internal yang disebut backing field. Field ini hanya dapat diakses dari dalam custom accessor melalui keyword field. Saat kita menulis var harga: Int = 0, kompilator membuat field internal serta getter dan setter default yang membaca dan menulis field tersebut.
Custom setter memungkinkan kita memvalidasi setiap penugasan. Karena keyword field merujuk ke penyimpanan internal, kita harus menulis field = value (bukan harga = value) untuk menghindari pemanggilan setter secara rekursif yang akan menyebabkan galat stack overflow.
Contoh Property dengan Custom Accessor #
Contoh berikut mendemonstrasikan property var dengan custom setter yang menolak nilai negatif, property var dengan custom getter yang memberikan nilai default, serta property lateinit var yang diisi setelah object dibuat.
// properties.kt
// Mendemonstrasikan property var, val, late-init, dan backing field sederhana.
class Buku(judul: String, hargaAwal: Int) {
val judul: String = judul
var harga: Int = hargaAwal
set(value) {
if (value >= 0) {
field = value
}
}
var jumlahHalaman: Int = 0
get() = if (field > 0) field else 1
}
class Layar {
lateinit var judul: String
fun siapTampil(): Boolean = ::judul.isInitialized
}
fun main() {
val buku = Buku("Belajar Kotlin", 75000)
println("Judul: ${buku.judul}")
println("Harga awal: ${buku.harga}")
buku.harga = -5000
println("Setelah set -5000: ${buku.harga}")
buku.harga = 80000
println("Setelah set 80000: ${buku.harga}")
buku.jumlahHalaman = 0
println("Halaman (field=0): ${buku.jumlahHalaman}")
buku.jumlahHalaman = 120
println("Halaman (field=120): ${buku.jumlahHalaman}")
val layar = Layar()
println("Layar judul terisi? ${layar.siapTampil()}")
layar.judul = "Dashboard Penjualan"
println("Layar judul terisi? ${layar.siapTampil()}")
println("Judul layar: ${layar.judul}")
}Output yang Dihasilkan:
Judul: Belajar Kotlin
Harga awal: 75000
Setelah set -5000: 75000
Setelah set 80000: 80000
Halaman (field=0): 1
Halaman (field=120): 120
Layar judul terisi? false
Layar judul terisi? true
Judul layar: Dashboard PenjualanMari kita amati peran tiap bagian:
val judul: String = judul: property read-only. Nilai ditugaskan satu kali saat inisialisasi dan tidak dapat diubah lagi.var harga: Int = hargaAwaldengan custom setter: saat pemanggil menulisbuku.harga = -5000, setter memeriksa kondisivalue >= 0. Karena-5000tidak memenuhi kondisi, penugasan kefieldtidak terjadi dan nilaihargatetap75000.field = value: keywordfieldmerujuk ke penyimpanan internal property. Bila kita menulisharga = valuedi dalam setter, kompilator akan memanggil setter yang sama lagi tanpa henti — ini adalah jebakan umum yang harus dihindari.var jumlahHalaman: Int = 0dengan custom getterget() = if (field > 0) field else 1: saat field bernilai0, getter mengembalikan1sebagai default. Saat field bernilai120, getter mengembalikan120apa adanya. Nilai default ini tidak mengubah field internal.lateinit var judul: String: modifierlateinitmemberi tahu kompilator bahwa property akan diisi belakangan. Sebelum diisi, property tidak boleh dibaca.::judul.isInitialized: ekspresi ini memeriksa apakah propertylateinitsudah diberi nilai. Berguna untuk menghindariUninitializedPropertyAccessExceptionsaat runtime.
Property val Tidak Memiliki Setter #
Property val hanya boleh memiliki custom getter, tidak boleh memiliki setter. Hal ini konsisten dengan sifat read-only: nilai hanya ditentukan satu kali saat inisialisasi dan tidak dapat diubah. Bila sebuah val ingin mengembalikan nilai hasil komputasi, kita cukup menulis custom getter tanpa menyentuh field. Contoh: val pajak: Int get() = harga / 10.
Modifier lateinit #
Modifier lateinit dirancang untuk property var bertipe non-primitif (biasanya object) yang akan diisi setelah object dibuat — misalnya pada framework yang memerlukan injeksi dependensi atau pada pengujian dengan setup terpisah. Tiga batasan penting: hanya boleh var (bukan val), tidak boleh bertipe primitif (Int, Boolean, dll.), dan tidak boleh memiliki custom getter atau setter.
Referensi Lanjutan #
- Properties
— panduan resmi deklarasi property
val,var, danlateinit
Ringkasan Property #
Property Kotlin menyatukan field dan accessor dalam satu deklarasi. Keyword val menandakan read-only, var menandakan mutable. Custom accessor dengan keyword field memberi kontrol penuh atas pembacaan dan penugasan tanpa kehilangan struktur internal. Modifier lateinit memungkinkan penundaan inisialisasi property non-null. Pada chapter Primary Constructor berikutnya, kita akan melihat bagaimana property dideklarasikan langsung pada daftar parameter constructor untuk membuat class yang ringkas namun ekspresif.