ProgrammingAndroid Developer

What are extension properties in Kotlin, how are they implemented, and what limitations do they have compared to regular properties?

Pass interviews with Hintsage AI assistant

Answer.

Extension properties are extensions for classes that allow you to add getters and setters without the ability to add state (backing field). In Java, this is not possible, and the equivalent would be writing utility methods. Historically, to add functionality, static methods or Wrapper objects have had to be used.

Problem: Third-party classes often lack the necessary properties. We want to extend a class concisely and safely without breaking encapsulation.

Solution: In Kotlin, you can declare an extension property, which looks like a regular property but is implemented as functions. This allows for the extension of types to which we do not have access to the source code in a convenient way.

Code example:

val String.firstChar: Char get() = this[0] println("Kotlin".firstChar) // K

Key features:

  • Extension property is syntactic sugar and cannot have state (you cannot declare a backing field).
  • For set-properties, they are implemented only through a function.
  • They only work with the public API of the class and cannot access private members.

Trick Questions.

Can you add a backing field (state) to an extension property?

No, the extension property only computes the value on the fly and cannot hold state.

Can extension properties override properties in inherited classes?

No, extension properties (like extension functions) are inherently static: they cannot be overridden or virtual.

How is an extension property compiled, and why is it not a syntactical equivalent of a regular property?

An extension property actually compiles into a static getter (and/or setter) function. They are not included in the class entities and are only visible in the context of the file where they are declared.

Typical mistakes and anti-patterns

  • Expecting access to private members of a class within an extension property.
  • Trying to implement state storage through an extension property.
  • Abuse of extension properties instead of regular properties when it's unnecessary.

Real-life example

Negative case

A developer tried to add an extension property for storing the state of "visited" in standard Android Views:

var View.isVisited: Boolean get() = ... set(value) { ... } // Error: no storage

Pros:

  • Concise syntax

Cons:

  • Expecting impossible functionality (it's not possible to store state)
  • Errors during runtime

Positive case

An extension property for String was implemented to obtain an extended format:

val String.asTitle: String get() = this.replaceFirstChar { it.uppercase() }

Pros:

  • Convenience in adding functionality
  • Absence of third-party utilities
  • Easy maintenance

Cons:

  • No state storage (if that's required, another pattern is needed)