Extension property en Kotlin — qué es, sintaxis y uso

Autor: IT Sectr Publicado: 2026-06-21 Tiempo de lectura: 8 min

extension property — un mecanismo de Kotlin que permite agregar nuevas propiedades a clases existentes sin herencia y sin modificar el código fuente. A diferencia de las extension functions, las extension properties no pueden almacenar estado — se declaran solo con un getter y, opcionalmente, un setter, ya que no tienen un backing field. Según Kotlin Documentation, 2025, las extension properties se compilan en métodos estáticos getter y setter con el receiver como primer parámetro.

Puntos clave

  • Extension property — una propiedad con un receiver type, accesible mediante la sintaxis de propiedades de Kotlin
  • Sin backing field — una extension property no puede almacenar estado, solo calcular
  • Getter obligatorio, setter opcional — se declaran como funciones de extensión normales
  • Tipos anulables compatibles: el receiver puede ser nullable con una verificación interna
  • Mutable extension property — solo cuando se declara como var con getter y setter

¿Qué es una extension property en Kotlin?

Una extension property es una construcción sintáctica de Kotlin que agrega una propiedad a un tipo existente sin cambiar su declaración. La propiedad se declara con un receiver type y debe contener un getter. La diferencia clave con las propiedades normales es la ausencia de un backing field: una extension property no puede almacenar datos, solo calcularlos basándose en el objeto receiver.

Según la Encuesta de Kotlin Foundation (2024), las extension properties son menos populares que las extension functions — aproximadamente el 45% de los desarrolladores las usan regularmente. Esto se debe a la limitación de no tener estado, lo que reduce el ámbito de aplicación. Sin embargo, para propiedades calculadas que están lógicamente vinculadas a un tipo, las extension properties son la opción más concisa.

Las extension properties se compilan en un par de métodos estáticos getter y setter. A nivel de bytecode, no hay diferencia entre llamar a una extension property y llamar a una extension function — ambas se convierten en métodos estáticos con un parámetro receiver. Según JetBrains (Kotlin Docs, 2025), no hay ninguna sobrecarga.

Use extension properties para valores calculados cortos que deben verse como propiedades en lugar de llamadas a métodos — esto mejora la legibilidad del código y cumple con el Principio de Acceso Uniforme.

Sintaxis de extension property: val y var

Para declarar una extension property, use una sintaxis similar a la de una propiedad normal, pero con el prefijo del receiver type. val declara una extension property de solo lectura con un getter obligatorio, var declara una mutable con un getter y un setter opcional.

kotlin
// Read-only extension property
val String.isEmail: Boolean
    get() = this.contains("@") && this.contains(".")

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

Nota: una extension property se llama sin paréntesis — str.isEmail, no str.isEmail(). Esta es la diferencia clave entre una extension property y una extension function: una propiedad parece un campo, aunque en realidad se calcula a través de un getter.

Generic extension property

Las extension properties pueden ser genéricas — el receiver puede usar parámetros de tipo genérico. Esto permite crear propiedades universales que funcionan con cualquier tipo de colección.

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 propiedad secondOrNull funciona para cualquier tipo T, devolviendo el segundo elemento de la lista o null si hay menos de dos elementos. Este es un ejemplo típico donde una extension property es más apropiada que una función — su acceso parece la lectura de un campo.

Por qué una extension property no puede almacenar estado

Una extension property no puede tener un backing field porque no se agrega a los metadatos de la clase — existe solo como un par de funciones estáticas getter/setter. Backing field (la palabra clave field en Kotlin) es un campo interno de la clase que almacena el valor de la propiedad. Una extension property no tiene acceso a la estructura interna de la clase.

kotlin
// ❌ ERROR: extension property cannot have a backing field
var String.cachedValue: String
    get() = "computed"
    set(value) {
        field = value // field is not accessible!
    }

// ✅ CORRECT: use external storage
val cache = MutableMap<String, String>()

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

Un Map externo en el ejemplo resuelve el problema de almacenamiento pero crea otro — una fuga de memoria. Los valores obtenidos a través de una extension property viven en el Map para siempre si no se limpian. Esta limitación hace que las extension properties no sean adecuadas para almacenar caché o datos temporales.

Para almacenamiento en caché, se recomienda usar un WeakHashMap o mecanismos con limpieza automática. JetBrains recomienda evitar el uso de var extension properties con almacenamiento externo en código de producción sin una gestión cuidadosa del ciclo de vida.

Extension property vs extension function: cuándo elegir qué

La elección entre una extension property y una extension function depende de la semántica: una propiedad describe una característica de un objeto, mientras que una función describe una acción. El Principio de Acceso Uniforme establece: el cliente no debe saber si un valor se calcula o se almacena. Si el valor se puede representar como una característica (longitud, tamaño, estado) — use una propiedad.

CriterioExtension propertyExtension function
LlamadaSin paréntesis: obj.propertyCon paréntesis: obj.function()
SemánticaCaracterística, atributoAcción, operación
Backing fieldNo compatibleNo aplicable
ParámetrosSolo getter/setterCualquier parámetro
RendimientoIgual (método estático)Igual (método estático)
Ejemplotext.lengthtext.isEmail()

La regla es simple: si la operación acepta parámetros — use una extension function. Si es un valor calculado simple sin parámetros — use una extension property. Según Android Architecture Guide (Google, 2025), se debe dar preferencia a las extension properties para el acceso a datos y a las extension functions para operaciones con efectos secundarios.

Mutable extension property con var y setter

Una extension property con la palabra clave var admite un setter, pero sin la capacidad de almacenar un valor — el setter generalmente realiza un efecto secundario o guarda datos en un almacenamiento externo. La sintaxis es similar a las propiedades mutables de clase.

kotlin
// Mutable extension property with 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 propiedad lastChar es un ejemplo clásico de la documentación de Kotlin. El getter devuelve el último carácter de StringBuilder, el setter lo reemplaza con un nuevo valor. Nota: el estado se almacena en el propio StringBuilder (a través de setCharAt), no en un campo separado — este es un uso correcto de una extension property.

Ejemplos prácticos de extension properties

En proyectos reales, las extension properties se usan más a menudo para simplificar el acceso a datos de colecciones, calcular tamaños o estados de elementos de UI, y crear una API conveniente sobre clases existentes. La biblioteca estándar de Kotlin usa activamente este mecanismo: size, indices, lastIndex para colecciones son extension properties.

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

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

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

// Null check via safe receiver
val String?.isNullOrBlank: Boolean
    get() = this == null || this.isBlank()

La extension property isVisible para View es un ejemplo que todo desarrollador Android debería conocer. En lugar de view.visibility == View.VISIBLE, puede escribir view.isVisible. Esto no solo es más corto, sino que también se lee como lenguaje natural: "si la vista es visible". A pesar de su simplicidad, estas propiedades mejoran significativamente la legibilidad del código.

Preguntas frecuentes

¿Se puede declarar una extension property para un companion object?

No, las extension properties no se pueden declarar para un companion object o una declaración de object. El mecanismo de extensión se aplica solo a clases, interfaces y tipos anulables. Para object, use funciones regulares de nivel superior.

¿En qué se diferencia una extension property de una inline property?

Una inline property (con el modificador inline) es un mecanismo de Kotlin para llamar a un getter/setter sin crear un objeto de propiedad. Una extension property siempre se compila en un método estático, mientras que una inline property se compila en una llamada sin envoltorio. Resuelven problemas diferentes: una extension property agrega una propiedad a un tipo existente, mientras que inline optimiza las llamadas a sus propias propiedades.

¿Las extension properties admiten anotaciones?

, una extension property puede tener anotaciones, pero solo a nivel de declaración. No se puede anotar por separado el getter o el setter de una extension property — a diferencia de las propiedades de clase normales. Ejemplo: @JvmName("getIsValid") val String.isValid get() = true.

¿Se puede usar una extension property con el companion object de una clase?

No, las extension properties no se pueden declarar con un companion object como receiver. Esta es una limitación del lenguaje — una extension property solo funciona con instancias de tipo, mientras que un companion object es un contexto estático. Use funciones de extensión de nivel superior o constantes.

¿Afecta una extension property al tamaño del APK?

Mínimamente. Cada extension property agrega un método getter estático (y opcionalmente un setter) al bytecode compilado. En comparación, crear una clase envoltorio con la misma propiedad agrega una clase completa. Las extension properties son un enfoque más ligero para extender la funcionalidad.

Resumen

  • Extension property — una propiedad calculada para un tipo existente sin herencia
  • Sin backing field — el estado no se almacena, solo se calcula a través de un getter
  • var con setter — posible, pero requiere almacenamiento externo para escribir datos
  • Sintaxis — val/var con receiver type y getter obligatorio
  • Rendimiento — sin sobrecarga, se compila en un método estático
  • Uso — características calculadas: longitud, estado, tamaño, comprobaciones
  • Limitación — no es adecuado para almacenar estado, almacenamiento en caché sin gestión de memoria

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también