extension property — механизам у Kotlin који омогућује додавање нових својстава постојећим класама без наслеђивања и без измене изворног кода. За разлику од extension functions, својства-проширења не могу чувати стање — она се декларишу само са гетером и опционално сетером, јер немају backing field. Према Kotlin Documentation, 2025, extension properties се компилирају у статичке методе getter и setter са receiver-ом као првим параметром.
Главно
extension property — је синтаксна конструкција Kotlin-а која додаје својство постојећем типу без мењања његове декларације. Својство се декларише са наводом receiver-типа и обавезно садржи гетер. Кључна разлика у односу на обична својства — непостојање backing field: extension property не може да чува податке, већ их само израчунава на основу receiver-објекта.
Према Kotlin Foundation Survey (2024), extension properties су мање популарне од extension functions — око 45% програмера их редовно користи. То је због ограничења непостојања стања, што сужава област примене. Ипак, за израчуната својства која су логички везана за тип, extension properties су најконцизнија опција.
Extension properties се компилирају у пар статичких метода getter и setter. На нивоу бајт-кода нема разлике између позива extension property и extension function — оба постају статичке методе са receiver параметром. Према подацима JetBrains (Kotlin Docs, 2025), надокретје је потпуно одсутан.
Користите extension properties за кратке израчунате вредности које треба да изгледају као својства, а не као позиви метода — то побољшава читљивост кода и поштује принцип једнаког приступа.
За декларисање extension property користи се синтакса слична обичном својству, али са префиксом receiver-типа. val декларише read-only extension property са обавезним гетером, var — mutable са гетером и опционалним сетером.
// Read-only extension property
val String.isEmail: Boolean
get() = this.contains("@") && this.contains(".")
// Poziv
val valid = "test@test.com".isEmail
Обратите пажња: extension property се позива без заграда — str.isEmail, а не str.isEmail(). То је кључна разлика између extension property и extension function: property изгледа као поље, иако се заправо израчунава кроз гетер.
Extension properties могу бити опште — receiver може да користи generic параметре. То омогућује стварање универзалних својстава која раде са било којим типом колекције.
val List<T>.secondOrNull: T?
get() = if (size >= 2) this[1] else null
val items = listOf("a", "b", "c")
val second = items.secondOrNull // "b"
Својство secondOrNull ради за било који тип T, враћајући други елемент листе или null ако има мање од два елемента. То је типичан примјер где је extension property прикладнија од функције — приступ изгледа као читање поља.
Extension property не може имати backing field јер се не додаје у метаподатке класе — постоји само као пар статичких функција getter/setter. Backing field (кључна реч field у Kotlin-у) — је унутрашње поље класе које чува вредност својства. Extension property нема приступ унутрашњој структури класе.
// ❌ GREŠKA: extension property ne može imati backing field
var String.cachedValue: String
get() = "computed"
set(value) {
field = value // polje nije dostupno!
}
// ✅ ISPRAVNO: koristite spoljašnje skladište
val cache = MutableMap<String, String>()
var String.cachedValue: String
get() = cache[this] ?: ""
set(value) { cache[this] = value }
Спољашњи Map у примјеру решава проблем складиштења, али ствара други — цурење меморије. Вредности добијене кроз extension property живе у Map-у заувек ако се не очисте. То ограничење чини extension properties непогодним за кеширање или чување привремених података.
За кеширање се препоручује коришћење WeakHashMap или механизама са аутоматским чишћењем. JetBrains препоручује да се избегава коришћење var extension properties са спољашњим складиштем у производном коду без пажљивог управљања животним циклусом.
Избор између extension property и extension function зависи од семантике: својство описује карактеристику објекта, а функција — радњу. Принцип једнаког приступа (Uniform Access Principle) каже: клијент не треба да зна да ли се вредност израчунава или чува. Ако се вредност може представити као карактеристика (дужина, величина, статус) — користите property.
| Критеријум | Extension property | Extension function |
|---|---|---|
| Позив | Без заграда: obj.property | Са заградама: obj.function() |
| Семантика | Карактеристика, атрибут | Радња, операција |
| Backing field | Није подржан | Није примењиво |
| Параметри | Само getter/setter | Било који параметри |
| Перформансе | Исто (статичка метода) | Исто (статичка метода) |
| Примјер | text.length | text.isEmail() |
Правило је једноставно: ако операција прихвата параметре — користите extension function. Ако је то једноставна израчуната вредност без параметара — extension property. Према подацима Android Architecture Guide (Google, 2025), предност треба дати extension properties за приступ подацима и extension functions за операције са нуспоредним ефектима.
Extension property са кључном речју var подржава сетер, али без могућности чувања вредности — сетер обично извршава нуспоредну радњу или чува податке у спољашњем складишту. Синтакса је аналогна mutable својствима класа.
// Mutable extension property sa setterom
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!
Својство lastChar — класичан примјер из документације Kotlin-а. Getter враћа последњи знак StringBuilder-а, setter га замењује новом вредношћу. Обратите пажња: стање се чува у самом StringBuilder-у (кроз setCharAt), а не у одвојеном пољу — то је исправно коришћење extension property.
У реалним пројектима extension properties се најчешче користе за поједностављивање приступа подацима колекција, израчунавање величина или статуса UI елемената и креирање погодног API-ја над постојећим класама. Стандардна библиотека Kotlin активно користи овај механизам: size, indices, lastIndex за колекције — то су extension properties.
// Extension properties za kolekcije
val List<Int>.sumFast: Int
get() = fold(0) { acc, i -> acc + i }
val String.half: String
get() = this.substring(0, length / 2)
// Extension property za Android View
val View.isVisible: Boolean
get() = visibility == View.VISIBLE
// Null provera putem sigurnog receivera
val String?.isNullOrBlank: Boolean
get() = this == null || this.isBlank()
Extension property isVisible за View — примјер који сваки Android програмер треба да зна. Уместо view.visibility == View.VISIBLE може се писати view.isVisible. То је не само краће, већ се чита као природан језик: „ако је прозор видљив“. Упркос једноставности, оваква својства значајно побољшавају читљивост кода.
Често постављана питања
Не, extension properties не могу бити декларисане за companion object или object declaration. Механизам extension се примењује само на класе, интерфејсе и nullable типове. За object користите обичне функције највишег нивоа.
Inline својство (са модификатором inline) — механизам Kotlin-а за позивање гетера/сетера без креирања објекта-својства. Extension property се увек компилира у статичку методу, а inline својство — у позив без овојница. Оне решавају различите задатке: extension property додаје својство постојећем типу, inline оптимизује позиве сопствених својстава.
Да, extension property може да садржи анотације, али само на нивоу декларације. Не могу се анотирати одвојено getter или setter extension property — за разлику од обичних својстава класе. Примјер: @JvmName(„getIsValid“) val String.isValid get() = true.
Не, extension properties се не могу декларисати са companion object као receiver. То је ограничење језика — extension property ради само са инстанцама типова, а companion object је статички контекст. Користите extension функције највишег нивоа или константе.
Минимално. Свака extension property додаје једну статичку методу getter (и опционално setter) у компилирани бајт-код. За поређење: креирање класе овојнице са истим својством додаје целу класу. Extension properties — лакши приступ проширењу функционалности.
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође