How to Create Extension Property in Kotlin: Simple Guide
extension property by defining a property outside the class using the syntax val ClassName.propertyName: Type or var ClassName.propertyName: Type. Extension properties cannot have backing fields, so you must provide a getter (and optionally a setter) to compute or store the value.Syntax
An extension property is declared by prefixing the property name with the class name and a dot. You use val for read-only or var for mutable properties. Since extension properties cannot store data, you must define a getter to return a value, and optionally a setter to set a value.
ClassName.propertyName: Type- declares the property for the class.get() = ...- defines how to get the property value.set(value) { ... }- defines how to set the property value (only forvar).
val ClassName.propertyName: Type
get() = /* return computed value */
var ClassName.propertyName: Type
get() = /* return computed value */
set(value) { /* handle setting value */ }Example
This example shows how to add an extension property lastChar to the String class that returns the last character of the string. It also shows a mutable extension property lastCharMutable that allows changing the last character by creating a new string.
val String.lastChar: Char
get() = this[this.length - 1]
var String.lastCharMutable: Char
get() = this[this.length - 1]
set(value) {
// Since String is immutable, create a new string with the last char replaced
val newString = this.substring(0, this.length - 1) + value
println("New string after setting lastCharMutable: $newString")
}
fun main() {
val word = "hello"
println(word.lastChar) // Output: o
var mutableWord = "hello"
mutableWord.lastCharMutable = 'y' // Prints: New string after setting lastCharMutable: helly
}Common Pitfalls
Extension properties cannot have backing fields, so you cannot store data directly inside them. Trying to use field inside an extension property will cause a compile error. Also, extension properties do not actually modify the original class; they only provide computed values or side effects.
Another common mistake is expecting extension properties to work like normal properties with storage, but they are just syntactic sugar for functions.
/* Wrong: Trying to use backing field in extension property */ // val String.badProperty: Int = 0 // Error: Extension property cannot have initializer /* Correct: Use getter to compute value */ val String.goodProperty: Int get() = this.length
Quick Reference
| Feature | Description |
|---|---|
| Declaration | val/var ClassName.propertyName: Type |
| Backing Field | Not allowed in extension properties |
| Getter | Must provide to compute value |
| Setter | Optional for var, to handle value setting |
| Usage | Access like normal property on class instances |