ProgrammingAndroid Developer

What are inline set/get accessors for properties in Kotlin, what is their purpose and how to use them correctly? Reveal the specifics of inlining, provide an example, describe problematic areas.

Pass interviews with Hintsage AI assistant

Answer.

Background:

In Kotlin, access to properties is done through getter and setter methods. To achieve higher performance, developers added the inline modifier for accessors, allowing the JVM to optimize calls at compile time by inserting the body of the get/set directly into the calling code.

Problem:

Regular accessor methods are created for each property, which increases call overhead (especially when accessed frequently). Sometimes developers use separate get/set logic but want to avoid the function call overhead.

Solution:

Use the inline modifier on the getter or setter if their implementation is short and does not contain heavy code. This reduces overhead, particularly in hot paths. Note that inlining only works for top-level properties and properties in companion objects and object objects, not in regular classes due to JVM inheritance principles.

Code example:

inline var Int.asHex: String get() = Integer.toHexString(this) set(value) {} inline val String.firstUpperCase: String get() = if (isEmpty()) this else this[0].uppercase() + substring(1)

Key features:

  • Inline get/set can only be applied to top-level or object properties.
  • Inline accessor inserts the body of the method directly at the call site for time savings.
  • Inline accessor does not allow the use of backing fields.

Tricky questions.

Can inline get/set be used with regular class properties?

No, inlining for getters and setters is only allowed for top-level or object (including companion object) properties, not for properties inside classes, to avoid inheritance issues.

Is access to the backing field available in inline accessors?

No, inline accessors do not have a backing field, attempting to access it will result in a compile-time error.

Does inlining accessors always affect bytecode?

Inlining merely hints to the compiler about the possibility of embedding code. The JIT compiler may ignore this in some cases. Moreover, if the accessor contains heavy logic, the resulting effect may be the opposite.

Common mistakes and anti-patterns

  • Using inline accessors within classes
  • Attempting to access backing fields in inline getter/setter
  • Placing complex logic inside an inline accessor (over-inlining)

Real-life examples

Negative case

In a project, a large property was declared inline, but the getter handles heavy transformation used in a loop. The result is bloated bytecode, JIT disables inlining, performance drops.

Pros:

  • One getter for all logic

Cons:

  • Bloated bytecode, loss of JVM optimization

Positive case

An inline val was declared for converting a number to a string. The getter is called frequently in UI code. Performance remains high, bytecode is compact.

Pros:

  • Frequent use without overhead
  • Logic is not spread across the code

Cons:

  • Inline cannot be used for complex logic