skip to content

From Kotlin you extend a Java class that has getValue()/setValue(). How can you override the accessor behavior, and what are the rules for overriding a Java getter as a Kotlin property vs. a function?

level: seniorimportance: should knowfreq 30%

answer

  1. override var value with get()/set()
  2. super.value reaches Java accessor
  3. field = implicit backing field
  4. override the property, not getValue() as fun
  5. JVM names must stay getValue/setValue

basics

~20 s

In Kotlin you can override the inherited Java accessor pair as a property — declare override var value and supply custom get()/set(). You may also still override the raw methods, but using the property form is the idiomatic way.

solid answer

~40 s

When a Kotlin class extends a Java class exposing `getValue()`/`setValue()`, Kotlin sees an inherited synthetic property `value`. You override it by declaring `override var value: T` with a custom `get()` and `set(v)` body (or `override val value` for a getter-only). Kotlin matches the override to the Java accessor methods, so callers — Java or Kotlin — go through your overridden logic. You generally cannot `override fun getValue()` as a function while also treating it as a property in the same hierarchy, because Kotlin models the Java accessors as ONE property member; you override the property, not the individual methods. If you add a backing field via `field`, your `get()`/`set()` can store state. Visibility/type must stay compatible with the Java declaration; the JVM signatures generated must match `getValue`/`setValue`.

code

kotlin · 7 lines
kotlin
// Java: class Box { String getLabel(){...} void setLabel(String s){...} }
class TrimmedBox : Box() {
    override var label: String
        get() = super.label
        set(v) { super.label = v.trim() }
}
// Java callers using getLabel()/setLabel() now hit the trimming logic too.

go deeper

for a junior

Knows a subclass can change behavior but may not articulate property-override syntax.

for a middle

Writes override var value with get()/set() and uses super.value.

for a senior

Explains why you override the property (not the methods), backing-field rules, and JVM-signature compatibility.

for a principal

Designs Kotlin adapters over Java base classes preserving Java caller contracts, weighing mutability and dispatch correctness.

## The setup A Java superclass: ```java public class Base { public String getValue(){...} public void setValue(String v){...} } ``` From Kotlin, `Base` contributes a synthetic property `value: String` (read-write because both accessors exist). ## Overriding as a property Kotlin lets you override that inherited accessor pair using **property** syntax: ```kotlin class Derived : Base() { override var value: String get() = "computed-" + super.value // super.value calls Base.getValue() set(v) { super.value = v.trim() } // calls Base.setValue(...) } ``` - `override var value` lines up with `getValue`/`setValue` by JVM signature. - `super.value` reaches the Java parent's accessor. - Any caller (Java `getValue()` or Kotlin `obj.value`) now runs your overridden `get()`/`set()`. For a getter-only Java property, override with `override val value: String get() = ...`. ## Backing field Your overriding accessors can keep state with the implicit **`field`** identifier: ```kotlin override var value: String = "" get() = field.uppercase() set(v) { field = v.trim() } ``` `field` is the auto-generated backing field; it's only available inside the property's own accessors. ## Property vs function Because Kotlin folds the Java `getValue`/`setValue` pair into a **single property member**, you override the **property**, not each method. Trying to `override fun getValue()` clashes with the property view and is rejected by the compiler (the member is a property, not a function, from Kotlin's standpoint). Conversely, a non-conforming Java method (e.g. `fetchValue()`) is a function and you override it with `override fun fetchValue()`. ## Compatibility constraints - The override's **type** must be assignable-compatible with the Java return/param types. - Generated JVM names must be `getValue`/`setValue`/`isX` so dynamic dispatch from Java finds them. - You cannot widen visibility incorrectly or change the property's mutability to read-write if the parent only offered a getter (no inherited setter to override). ## Why it matters This is the bridge for **adapting Java framework classes** (e.g. extending a Java base in a Kotlin subclass) while presenting clean property semantics, and for inserting validation/transformation transparently to existing Java callers.

  • Can you change a getter-only Java property to read-write in your Kotlin subclass?
    No — there's no inherited setter to override. You'd have to add a new, separately named setter method; the property's mutability follows the Java parent.
  • What does `super.value` compile to?
    An invocation of the Java superclass accessor, e.g. super.getValue() / super.setValue(...).

saying these in an interview costs you the question

  • Trying to override fun getValue() separately while treating it as a property
  • Forgetting super.value delegates to the Java accessor
  • Using `field` outside the property's own accessors
  • Assuming you can make a getter-only property writable by adding override set()

context