Extension property in Kotlin — cos'è, sintassi e utilizzo

Autore: IT Sectr Pubblicato: 2026-06-21 Tempo di lettura: 8 min

extension property — un meccanismo Kotlin che permette di aggiungere nuove proprietà a classi esistenti senza ereditarietà e senza modificare il codice sorgente. A differenza delle extension functions, le extension properties non possono memorizzare stato — vengono dichiarate solo con un getter e, opzionalmente, un setter, poiché non hanno un backing field. Secondo Kotlin Documentation, 2025, le extension properties vengono compilate in metodi statici getter e setter con il receiver come primo parametro.

Punti chiave

  • Extension property — una proprietà con receiver type, accessibile tramite la sintassi delle proprietà Kotlin
  • Nessun backing field — una extension property non può memorizzare stato, solo calcolare
  • Getter obbligatorio, setter opzionale — dichiarati come normali extension functions
  • Tipi nullable supportati: il receiver può essere nullable con un controllo interno
  • Extension property mutabile — solo quando dichiarata come var con getter e setter

Cos'è una extension property in Kotlin?

Una extension property è una costruzione sintattica in Kotlin che aggiunge una proprietà a un tipo esistente senza modificarne la dichiarazione. La proprietà viene dichiarata con un receiver type e deve contenere un getter. La differenza chiave rispetto alle proprietà normali è l'assenza di backing field: una extension property non può memorizzare dati, solo calcolarli basandosi sull'oggetto receiver.

Secondo il Sondaggio Kotlin Foundation (2024), le extension properties sono meno popolari delle extension functions — circa il 45% degli sviluppatori le usa regolarmente. Ciò è dovuto alla limitazione di non avere stato, che restringe l'ambito di applicazione. Tuttavia, per proprietà calcolate logicamente legate a un tipo, le extension properties sono l'opzione più concisa.

Le extension properties vengono compilate in una coppia di metodi statici getter e setter. A livello di bytecode, non c'è differenza tra chiamare una extension property e chiamare una extension function — entrambe diventano metodi statici con un parametro receiver. Secondo JetBrains (Kotlin Docs, 2025), non c'è alcun overhead.

Usa le extension properties per valori calcolati brevi che devono sembrare proprietà piuttosto che chiamate a metodi — questo migliora la leggibilità del codice e segue il Principio di Accesso Uniforme.

Sintassi di extension property: val e var

Per dichiarare una extension property, usa una sintassi simile a una proprietà normale, ma con il prefisso del receiver type. val dichiara una extension property di sola lettura con un getter obbligatorio, var ne dichiara una mutabile con un getter e un setter opzionale.

kotlin
// Extension property di sola lettura
val String.isEmail: Boolean
    get() = this.contains("@") && this.contains(".")

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

Nota: una extension property viene chiamata senza parentesi — str.isEmail, non str.isEmail(). Questa è la differenza chiave tra una extension property e una extension function: una proprietà sembra un campo, anche se in realtà viene calcolata tramite un getter.

Extension property generica

Le extension properties possono essere generiche — il receiver può usare parametri di tipo generico. Questo permette di creare proprietà universali che funzionano con qualsiasi tipo di collezione.

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"

La proprietà secondOrNull funziona per qualsiasi tipo T, restituendo il secondo elemento della lista o null se ci sono meno di due elementi. Questo è un esempio tipico in cui una extension property è più appropriata di una funzione — il suo accesso sembra la lettura di un campo.

Perché una extension property non può memorizzare stato

Una extension property non può avere un backing field perché non viene aggiunta ai metadati della classe — esiste solo come coppia di funzioni statiche getter/setter. Backing field (la parola chiave field in Kotlin) è un campo interno della classe che memorizza il valore della proprietà. Una extension property non ha accesso alla struttura interna della classe.

kotlin
// ❌ ERRORE: extension property non può avere un backing field
var String.cachedValue: String
    get() = "computed"
    set(value) {
        field = value // campo non accessibile!
    }

// ✅ CORRETTO: usa archiviazione esterna
val cache = MutableMap<String, String>()

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

Una Map esterna nell'esempio risolve il problema di memorizzazione ma ne crea un altro — una perdita di memoria. I valori ottenuti tramite una extension property vivono nella Map per sempre se non vengono puliti. Questa limitazione rende le extension properties inadatte per la memorizzazione nella cache o per dati temporanei.

Per la cache, si raccomanda di usare un WeakHashMap o meccanismi con pulizia automatica. JetBrains raccomanda di evitare l'uso di var extension properties con memorizzazione esterna in codice di produzione senza un'attenta gestione del ciclo di vita.

Extension property vs extension function: quando scegliere cosa

La scelta tra una extension property e una extension function dipende dalla semantica: una proprietà descrive una caratteristica di un oggetto, mentre una funzione descrive un'azione. Il Principio di Accesso Uniforme afferma: il cliente non deve sapere se un valore viene calcolato o memorizzato. Se il valore può essere rappresentato come una caratteristica (lunghezza, dimensione, stato) — usa una proprietà.

CriterioExtension propertyExtension function
ChiamataSenza parentesi: obj.propertyCon parentesi: obj.function()
SemanticaCaratteristica, attributoAzione, operazione
Backing fieldNon supportatoNon applicabile
ParametriSolo getter/setterQualsiasi parametro
PrestazioniUguali (metodo statico)Uguali (metodo statico)
Esempiotext.lengthtext.isEmail()

La regola è semplice: se l'operazione accetta parametri — usa una extension function. Se è un semplice valore calcolato senza parametri — usa una extension property. Secondo la Guida all'Architettura Android (Google, 2025), si dovrebbe dare preferenza alle extension properties per l'accesso ai dati e alle extension functions per le operazioni con effetti collaterali.

Extension property mutabile con var e setter

Una extension property con la parola chiave var supporta un setter, ma senza la capacità di memorizzare un valore — il setter di solito esegue un effetto collaterale o salva dati in un archivio esterno. La sintassi è simile alle proprietà mutabili di classe.

kotlin
// Extension property mutabile con 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!

La proprietà lastChar è un esempio classico dalla documentazione Kotlin. Il getter restituisce l'ultimo carattere di StringBuilder, il setter lo sostituisce con un nuovo valore. Nota: lo stato è memorizzato nello stesso StringBuilder (tramite setCharAt), non in un campo separato — questo è un uso corretto di una extension property.

Esempi pratici di extension properties

Nei progetti reali, le extension properties sono più spesso usate per semplificare l'accesso ai dati delle collezioni, calcolare dimensioni o stati di elementi UI e creare un'API comoda sopra classi esistenti. La libreria standard Kotlin usa attivamente questo meccanismo: size, indices, lastIndex per le collezioni sono extension properties.

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

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

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

// Controllo null tramite receiver sicuro
val String?.isNullOrBlank: Boolean
    get() = this == null || this.isBlank()

L'extension property isVisible per View è un esempio che ogni sviluppatore Android dovrebbe conoscere. Invece di view.visibility == View.VISIBLE, puoi scrivere view.isVisible. Questo non è solo più corto, ma si legge anche come linguaggio naturale: "se la view è visibile". Nonostante la loro semplicità, tali proprietà migliorano significativamente la leggibilità del codice.

Domande frequenti

Si può dichiarare una extension property per un companion object?

No, le extension properties non possono essere dichiarate per un companion object o una object declaration. Il meccanismo di estensione si applica solo a classi, interfacce e tipi nullable. Per object, usa funzioni normali di livello superiore.

In cosa differisce una extension property da una inline property?

Una inline property (con il modificatore inline) è un meccanismo Kotlin per chiamare un getter/setter senza creare un oggetto proprietà. Una extension property viene sempre compilata in un metodo statico, mentre una inline property viene compilata in una chiamata senza wrapper. Risolvono problemi diversi: una extension property aggiunge una proprietà a un tipo esistente, mentre inline ottimizza le chiamate alle proprie proprietà.

Le extension properties supportano le annotazioni?

, una extension property può avere annotazioni, ma solo a livello di dichiarazione. Non è possibile annotare separatamente il getter o il setter di una extension property — a differenza delle proprietà di classe normali. Esempio: @JvmName("getIsValid") val String.isValid get() = true.

Si può usare una extension property con il companion object di una classe?

No, le extension properties non possono essere dichiarate con un companion object come receiver. Questa è una limitazione del linguaggio — una extension property funziona solo con istanze di tipo, mentre un companion object è un contesto statico. Usa funzioni di estensione di livello superiore o costanti.

Una extension property influisce sulla dimensione dell'APK?

Minimamente. Ogni extension property aggiunge un metodo getter statico (e opzionalmente un setter) al bytecode compilato. Per confronto, creare una classe wrapper con la stessa proprietà aggiunge un'intera classe. Le extension properties sono un approccio più leggero per estendere le funzionalità.

Riepilogo

  • Extension property — una proprietà calcolata per un tipo esistente senza ereditarietà
  • Nessun backing field — lo stato non viene memorizzato, solo calcolato tramite getter
  • var con setter — possibile, ma richiede archiviazione esterna per scrivere dati
  • Sintassi — val/var con receiver type e getter obbligatorio
  • Prestazioni — zero overhead, compilata in un metodo statico
  • Utilizzo — caratteristiche calcolate: lunghezza, stato, dimensione, controlli
  • Limitazione — non adatta per memorizzare stato, caching senza gestione della memoria

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche