Extension property di Kotlin — apa itu, sintaksis dan penerapan

Penulis: IT Sectr Diterbitkan: 2026-06-21 Waktu membaca: 8 mnt

extension property — mekanisme Kotlin yang memungkinkan menambahkan properti baru ke kelas yang sudah ada tanpa pewarisan dan tanpa mengubah kode sumber. Berbeda dengan extension functions, properti-ekstensi tidak dapat menyimpan status — mereka dideklarasikan hanya dengan getter dan opsional setter, karena tidak memiliki backing field. Menurut Kotlin Documentation, 2025, extension properties dikompilasi menjadi metode statis getter dan setter dengan receiver sebagai parameter pertama.

Poin utama

  • Extension property — properti dengan receiver type, dapat diakses melalui sintaksis properti Kotlin
  • Tidak ada backing field — extension property tidak dapat menyimpan status, hanya menghitung
  • Getter wajib, setter opsional — dideklarasikan seperti extension functions biasa
  • Tipe nullable didukung: receiver bisa nullable dengan pemeriksaan internal
  • Mutable extension property — hanya saat deklarasi var dengan getter dan setter

Apa itu extension property di Kotlin?

extension property — adalah konstruksi sintaksis Kotlin yang menambahkan properti ke tipe yang sudah ada tanpa mengubah deklarasinya. Properti dideklarasikan dengan menentukan tipe receiver dan wajib mengandung getter. Perbedaan utama dari properti biasa — tidak adanya backing field: extension property tidak dapat menyimpan data, hanya menghitungnya berdasarkan objek receiver.

Menurut Kotlin Foundation Survey (2024), extension properties kurang populer dibandingkan extension functions — sekitar 45% pengembang menggunakannya secara teratur. Hal ini disebabkan oleh batasan tidak adanya status, yang mempersempit area penerapan. Meskipun demikian, untuk properti yang dihitung dan secara logis terkait dengan tipe, extension properties adalah opsi yang paling ringkas.

Extension properties dikompilasi menjadi sepasang metode statis getter dan setter. Pada level bytecode, tidak ada perbedaan antara pemanggilan extension property dan extension function — keduanya menjadi metode statis dengan parameter receiver. Menurut data JetBrains (Kotlin Docs, 2025), overhead sama sekali tidak ada.

Gunakan extension properties untuk nilai hitung pendek yang harus terlihat seperti properti, bukan seperti pemanggilan metode — ini meningkatkan keterbacaan kode dan mematuhi prinsip akses seragam.

Sintaksis extension property: val dan var

Untuk mendeklarasikan extension property digunakan sintaksis yang mirip dengan properti biasa, tetapi dengan prefiks tipe receiver. val mendeklarasikan read-only extension property dengan getter wajib, var — mutable dengan getter dan setter opsional.

kotlin
// Extension property hanya baca
val String.isEmail: Boolean
    get() = this.contains("@") && this.contains(".")

// Panggilan
val valid = "test@test.com".isEmail

Perhatikan: extension property dipanggil tanpa tanda kurung — str.isEmail, bukan str.isEmail(). Ini adalah perbedaan utama antara extension property dan extension function: property terlihat seperti field, meskipun sebenarnya dihitung melalui getter.

Generic extension property

Extension properties dapat digeneralisasi — receiver dapat menggunakan parameter generic. Ini memungkinkan pembuatan properti universal yang bekerja dengan tipe koleksi apa pun.

kotlin
val List<T>.secondOrNull: T?
    get() = if (size >= 2) this[1] else null

val items = listOf("a", "b", "c")
val second = items.secondOrNull // "b"

Properti secondOrNull bekerja untuk tipe T apa pun, mengembalikan elemen kedua dari daftar atau null jika elemen kurang dari dua. Ini adalah contoh tipikal di mana extension property lebih tepat daripada fungsi — aksesnya terlihat seperti membaca field.

Mengapa extension property tidak dapat menyimpan status

Extension property tidak dapat memiliki backing field karena tidak ditambahkan ke metadata kelas — hanya ada sebagai sepasang fungsi statis getter/setter. Backing field (kata kunci field di Kotlin) — adalah field internal kelas yang menyimpan nilai properti. Extension property tidak memiliki akses ke struktur internal kelas.

kotlin
// ❌ ERROR: extension property tidak dapat memiliki backing field
var String.cachedValue: String
    get() = "computed"
    set(value) {
        field = value // field tidak dapat diakses!
    }

// ✅ BENAR: gunakan penyimpanan eksternal
val cache = MutableMap<String, String>()

var String.cachedValue: String
    get() = cache[this] ?: ""
    set(value) { cache[this] = value }

Map eksternal dalam contoh memecahkan masalah penyimpanan, tetapi menciptakan masalah lain — kebocoran memori. Nilai yang diperoleh melalui extension property hidup di Map selamanya jika tidak dibersihkan. Batasan ini membuat extension properties tidak cocok untuk caching atau penyimpanan data sementara.

Untuk caching, disarankan menggunakan WeakHashMap atau mekanisme dengan pembersihan otomatis. JetBrains merekomendasikan untuk menghindari penggunaan var extension properties dengan penyimpanan eksternal dalam kode produksi tanpa manajemen siklus hidup yang cermat.

Extension property vs extension function: kapan memilih apa

Pilihan antara extension property dan extension function tergantung pada semantik: properti menggambarkan karakteristik objek, fungsi menggambarkan tindakan. Prinsip akses seragam (Uniform Access Principle) mengatakan: klien tidak boleh tahu apakah nilai dihitung atau disimpan. Jika nilai dapat direpresentasikan sebagai karakteristik (panjang, ukuran, status) — gunakan property.

KriteriaExtension propertyExtension function
PemanggilanTanpa kurung: obj.propertyDengan kurung: obj.function()
SemantikKarakteristik, atributTindakan, operasi
Backing fieldTidak didukungTidak berlaku
ParameterHanya getter/setterParameter apa pun
KinerjaSama (metode statis)Sama (metode statis)
Contohtext.lengthtext.isEmail()

Aturannya sederhana: jika operasi menerima parameter — gunakan extension function. Jika ini adalah nilai hitung sederhana tanpa parameter — extension property. Menurut Android Architecture Guide (Google, 2025), preferensi harus diberikan pada extension properties untuk akses data dan extension functions untuk operasi dengan efek samping.

Mutable extension property dengan var dan setter

Extension property dengan kata kunci var mendukung setter, tetapi tanpa kemampuan menyimpan nilai — setter biasanya melakukan tindakan sampingan atau menyimpan data di penyimpanan eksternal. Sintaksis analog dengan properti mutable kelas.

kotlin
// Mutable extension property dengan setter
var StringBuilder.lastChar: Char
    get() = this[length - 1]
    set(value) {
        this.setCharAt(length - 1, value)
    }

val sb = StringBuilder("Kotlin")
println(sb.lastChar) // n
sb.lastChar = '!'
println(sb) // Kotli!

Properti lastChar — contoh klasik dari dokumentasi Kotlin. Getter mengembalikan karakter terakhir StringBuilder, setter menggantinya dengan nilai baru. Perhatikan: status disimpan di StringBuilder itu sendiri (melalui setCharAt), bukan di field terpisah — ini adalah penggunaan extension property yang benar.

Contoh praktis extension properties

Dalam proyek nyata, extension properties paling sering digunakan untuk menyederhanakan akses ke data koleksi, menghitung ukuran atau status elemen UI, dan membuat API yang nyaman di atas kelas yang sudah ada. Pustaka standar Kotlin secara aktif menggunakan mekanisme ini: size, indices, lastIndex untuk koleksi — ini adalah extension properties.

kotlin
// Extension properties untuk koleksi
val List<Int>.sumFast: Int
    get() = fold(0) { acc, i -> acc + i }

val String.half: String
    get() = this.substring(0, length / 2)

// Extension property untuk Android View
val View.isVisible: Boolean
    get() = visibility == View.VISIBLE

// Pemeriksaan null melalui receiver aman
val String?.isNullOrBlank: Boolean
    get() = this == null || this.isBlank()

Extension property isVisible untuk View — contoh yang harus diketahui setiap pengembang Android. Alih-alih view.visibility == View.VISIBLE, Anda bisa menulis view.isVisible. Ini tidak hanya lebih pendek, tetapi terbaca seperti bahasa alami: “jika tampilan terlihat”. Meskipun sederhana, properti semacam itu secara signifikan meningkatkan keterbacaan kode.

Pertanyaan yang sering diajukan

Bisakah extension property dideklarasikan untuk companion object?

Tidak, extension properties tidak dapat dideklarasikan untuk companion object atau object declaration. Mekanisme extension hanya berlaku untuk kelas, antarmuka, dan tipe nullable. Untuk object, gunakan fungsi biasa tingkat atas.

Apa perbedaan extension property dengan properti inline?

Properti inline (dengan pengubah inline) — mekanisme Kotlin untuk memanggil getter/setter tanpa membuat objek properti. Extension property selalu dikompilasi menjadi metode statis, sedangkan properti inline dikompilasi menjadi pemanggilan tanpa pembungkus. Mereka menyelesaikan tugas yang berbeda: extension property menambahkan properti ke tipe yang ada, inline mengoptimalkan pemanggilan properti sendiri.

Apakah extension property mendukung anotasi?

Ya, extension property dapat mengandung anotasi, tetapi hanya pada tingkat deklarasi. Getter atau setter extension property tidak dapat dianotasi secara terpisah — tidak seperti properti kelas biasa. Contoh: @JvmName(“getIsValid”) val String.isValid get() = true.

Bisakah extension property digunakan dengan companion object kelas?

Tidak, extension properties tidak dapat dideklarasikan dengan companion object sebagai receiver. Ini adalah batasan bahasa — extension property hanya bekerja dengan instance tipe, sedangkan companion object adalah konteks statis. Gunakan extension functions tingkat atas atau konstanta.

Apakah extension property mempengaruhi ukuran APK?

Minimal. Setiap extension property menambahkan satu metode statis getter (dan opsional setter) ke bytecode yang dikompilasi. Sebagai perbandingan: membuat kelas pembungkus dengan properti yang sama menambahkan seluruh kelas. Extension properties — pendekatan yang lebih ringan untuk memperluas fungsionalitas.

Kesimpulan

  • Extension property — properti yang dihitung untuk tipe yang ada tanpa pewarisan
  • Tidak ada backing field — status tidak disimpan, hanya dihitung melalui getter
  • var dengan setter — memungkinkan, tetapi memerlukan penyimpanan eksternal untuk menulis data
  • Sintaksis — val/var dengan tipe receiver dan getter wajib
  • Kinerja — tanpa overhead, dikompilasi menjadi metode statis
  • Penerapan — karakteristik yang dihitung: panjang, status, ukuran, pemeriksaan
  • Batasan — tidak cocok untuk penyimpanan status, caching tanpa manajemen memori

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga