Extension property v Kotlinu — co to je, syntaxe a použití

Autor: IT Sectr Publikováno: 2026-06-21 Doba čtení: 8 min

extension property — mechanismus Kotlinu, který umožňuje přidávat nové vlastnosti ke stávajícím třídám bez dědičnosti a bez změny zdrojového kódu. Na rozdíl od extension functions, vlastnosti-rozšíření nemohou ukládat stav — jsou deklarovány pouze s getterem a volitelně setterem, protože nemají backing field. Podle Kotlin Documentation, 2025 jsou extension properties kompilovány do statických metod getter a setter s receiver jako prvním parametrem.

Hlavní body

  • Extension property — vlastnost s receiver type, přístupná prostřednictvím syntaxe vlastností Kotlinu
  • Žádný backing field — extension property nemůže ukládat stav, pouze počítat
  • Getter je povinný, setter je volitelný — deklarují se jako běžné extension functions
  • Nullable typy jsou podporovány: receiver může být nullable s interní kontrolou
  • Mutable extension property — pouze při deklaraci var s getterem a setterem

Co je extension property v Kotlinu?

extension property — je syntaktická konstrukce Kotlinu, která přidává vlastnost k existujícímu typu bez změny jeho deklarace. Vlastnost je deklarována s uvedením receiver-typu a povinně obsahuje getter. Klíčový rozdíl oproti běžným vlastnostem — chybějící backing field: extension property nemůže ukládat data, pouze je počítá na základě receiver-objektu.

Podle Kotlin Foundation Survey (2024) jsou extension properties méně populární než extension functions — asi 45% vývojářů je používá pravidelně. To je způsobeno omezením chybějícího stavu, což zužuje oblast použití. Nicméně pro počítané vlastnosti logicky spojené s typem jsou extension properties nejvýstižnější možností.

Extension properties jsou kompilovány do dvojice statických metod getter a setter. Na úrovni bajtkódu není rozdíl mezi voláním extension property a extension function — obě se stávají statickými metodami s parametrem receiver. Podle údajů JetBrains (Kotlin Docs, 2025) je režie zcela nulová.

Používejte extension properties pro krátké počítané hodnoty, které by měly vypadat jako vlastnosti, ne jako volání metod — to zlepšuje čitelnost kódu a dodržuje princip jednotného přístupu.

Syntaxe extension property: val a var

Pro deklaraci extension property se používá syntaxe podobná běžné vlastnosti, ale s prefixem receiver-typu. val deklaruje read-only extension property s povinným getterem, var — mutable s getterem a volitelným setterem.

kotlin
// Extension property pouze pro čtení
val String.isEmail: Boolean
    get() = this.contains("@") && this.contains(".")

// Volání
val valid = "test@test.com".isEmail

Všimněte si: extension property se volá bez závorek — str.isEmail, nikoli str.isEmail(). To je klíčový rozdíl mezi extension property a extension function: property vypadá jako pole, i když je ve skutečnosti počítána prostřednictvím getteru.

Generic extension property

Extension properties mohou být zobecněné — receiver může používat generické parametry. To umožňuje vytvářet univerzální vlastnosti pracující s jakýmkoli typem kolekce.

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"

Vlastnost secondOrNull funguje pro libovolný typ T a vrací druhý prvek seznamu nebo null, pokud je prvků méně než dva. To je typický příklad, kde je extension property vhodnější než funkce — přístup vypadá jako čtení pole.

Proč extension property nemůže ukládat stav

Extension property nemůže mít backing field, protože není přidávána do metadat třídy — existuje pouze jako dvojice statických funkcí getter/setter. Backing field (klíčové slovo field v Kotlinu) — je interní pole třídy, které ukládá hodnotu vlastnosti. Extension property nemá přístup k interní struktuře třídy.

kotlin
// ❌ CHYBA: extension property nemůže mít backing field
var String.cachedValue: String
    get() = "computed"
    set(value) {
        field = value // pole není přístupné!
    }

// ✅ SPRÁVNĚ: použijte externí úložiště
val cache = MutableMap<String, String>()

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

Externí Map v příkladu řeší problém ukládání, ale vytváří jiný — únik paměti. Hodnoty získané prostřednictvím extension property žijí v Map věčně, pokud nejsou vyčištěny. Toto omezení činí extension properties nevhodnými pro ukládání do mezipaměti nebo dočasných dat.

Pro ukládání do mezipaměti se doporučuje používání WeakHashMap nebo mechanismů s automatickým čištěním. JetBrains doporučuje vyhýbat se používání var extension properties s externím úložištěm v produkčním kódu bez pečlivé správy životního cyklu.

Extension property vs extension function: kdy co zvolit

Volba mezi extension property a extension function závisí na sémantice: vlastnost popisuje charakteristiku objektu, funkce popisuje akci. Princip jednotného přístupu (Uniform Access Principle) říká: klient by neměl vědět, zda je hodnota počítána nebo ukládána. Pokud lze hodnotu prezentovat jako charakteristiku (délka, velikost, stav) — použijte property.

KritériumExtension propertyExtension function
VoláníBez závorek: obj.propertySe závorkami: obj.function()
SémantikaCharakteristika, atributAkce, operace
Backing fieldNení podporovánNení relevantní
ParametryPouze getter/setterLibovolné parametry
VýkonStejný (statická metoda)Stejný (statická metoda)
Příkladtext.lengthtext.isEmail()

Pravidlo je jednoduché: pokud operace přijímá parametry — použijte extension function. Pokud se jedná o jednoduchou počítanou hodnotu bez parametrů — extension property. Podle údajů Android Architecture Guide (Google, 2025) by měly být upřednostňovány extension properties pro přístup k datům a extension functions pro operace s vedlejšími účinky.

Mutable extension property s var a setterem

Extension property s klíčovým slovem var podporuje setter, ale bez možnosti ukládat hodnotu — setter obvykle provádí vedlejší účinek nebo ukládá data do externího úložiště. Syntaxe je analogická mutabilním vlastnostem tříd.

kotlin
// Mutable extension property se setterem
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!

Vlastnost lastChar — klasický příklad z dokumentace Kotlinu. Getter vrací poslední znak StringBuilderu, setter jej nahrazuje novou hodnotou. Všimněte si: stav je ukládán v samotném StringBuilderu (prostřednictvím setCharAt), nikoli v samostatném poli — to je správné použití extension property.

Praktické příklady extension properties

V reálných projektech se extension properties nejčastěji používají pro zjednodušení přístupu k datům kolekcí, výpočet velikostí nebo stavů prvků UI a vytváření pohodlného API nad stávajícími třídami. Standardní knihovna Kotlinu aktivně používá tento mechanismus: size, indices, lastIndex pro kolekce — to jsou extension properties.

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

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

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

// Kontrola null prostřednictvím bezpečného receiveru
val String?.isNullOrBlank: Boolean
    get() = this == null || this.isBlank()

Extension property isVisible pro View — příklad, který by měl znát každý Android vývojář. Místo view.visibility == View.VISIBLE lze psát view.isVisible. Není to jen kratší, ale čte se jako přirozený jazyk: „pokud je pohled viditelný“. I přes svou jednoduchost takové vlastnosti výrazně zlepšují čitelnost kódu.

Často kladené otázky

Lze deklarovat extension property pro companion object?

Ne, extension properties nelze deklarovat pro companion object ani object declaration. Mechanismus extension se aplikuje pouze na třídy, rozhraní a nullable typy. Pro object použijte běžné funkce nejvyšší úrovně.

Čím se liší extension property od inline vlastnosti?

Inline vlastnost (s modifikátorem inline) — mechanismus Kotlinu pro volání getteru/setteru bez vytváření objektu-vlastnosti. Extension property je vždy kompilována do statické metody, zatímco inline vlastnost je kompilována do volání bez obalu. Řeší různé úkoly: extension property přidává vlastnost k existujícímu typu, inline optimalizuje volání vlastních vlastností.

Podporují extension properties anotace?

Ano, extension property může obsahovat anotace, ale pouze na úrovni deklarace. Getter nebo setter extension property nelze anotovat samostatně — na rozdíl od běžných vlastností třídy. Příklad: @JvmName(„getIsValid“) val String.isValid get() = true.

Lze použít extension property s companion object třídy?

Ne, extension properties nelze deklarovat s companion object jako receiver. To je omezení jazyka — extension property funguje pouze s instancemi typů, zatímco companion object je statický kontext. Použijte extension funkce nejvyšší úrovně nebo konstanty.

Ovlivňuje extension property velikost APK?

Minimálně. Každá extension property přidává jednu statickou metodu getter (a volitelně setter) do zkompilovaného bajtkódu. Pro srovnání: vytvoření obalové třídy se stejnou vlastností přidává celou třídu. Extension properties — lehčí přístup k rozšíření funkcionality.

Shrnutí

  • Extension property — počítaná vlastnost pro existující typ bez dědičnosti
  • Žádný backing field — stav se neukládá, pouze počítá prostřednictvím getteru
  • var se setterem — možné, ale vyžaduje externí úložiště pro zápis dat
  • Syntaxe — val/var s receiver-typem a povinným getterem
  • Výkon — nulová režie, kompilováno do statické metody
  • Použití — počítané charakteristiky: délka, stav, velikost, kontroly
  • Omezení — není vhodné pro ukládání stavu, cache bez správy paměti

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také