skip to content

A Java class has a method `boolean isEnabled()` and `void setEnabled(boolean)`. What does the synthetic Kotlin property look like, and what's special about the `is` prefix rule?

level: middleimportance: should knowfreq 55%

answer

  1. isX() keeps full name -> isEnabled
  2. getX() strips get -> enabled
  3. setter is setEnabled, not setIsEnabled
  4. is rule requires Boolean return
  5. don't lowercase to 'enabled' for is-accessors

basics

~10 s

Kotlin sees it as a property called enabled — but wait, no: for is-prefixed getters Kotlin keeps the whole name. The property is isEnabled, accessed as obj.isEnabled, and set via setEnabled.

solid answer

~30 s

For a boolean-style accessor named `isEnabled()`, Kotlin does NOT strip and lowercase to `enabled`. Instead the synthetic property keeps the full name `isEnabled`, so you read `obj.isEnabled`. The matching setter must be `setEnabled(...)` (the `is` is dropped to form the setter name), and assigning `obj.isEnabled = true` calls `setEnabled(true)`. This `is`-prefix rule applies specifically to accessors whose name starts with `is`; the getter form `getX()` instead produces property `x` with the `get` stripped and first letter lowercased. So `getEnabled()` -> `enabled`, but `isEnabled()` -> `isEnabled`. The accessor must return Boolean/boolean for the `is` rule.

code

kotlin · 4 lines
kotlin
// Java: class Feature { boolean isActive(){...} void setActive(boolean a){...} }
val f = Feature()
if (f.isActive) { /* isActive() */ }
f.isActive = false   // setActive(false)

go deeper

for a junior

Recognizes you write obj.isEnabled and it works.

for a middle

Correctly states isX keeps full name and pairs with setEnabled, not setIsEnabled.

for a senior

Explains the Boolean-return condition and the symmetry with Kotlin-generated JVM getter names.

for a principal

Reasons about API design consistency across the Kotlin/Java boundary and pitfalls when mixing get/is naming in a shared codebase.

## Two naming rules, side by side Kotlin derives the **synthetic property name** from the Java accessor name: - **`getX()` rule:** drop `get`, lowercase the first remaining letter. `getName()` -> `name`, `getURL()` -> `uRL`? Actually the decapitalization follows JavaBeans/Kotlin rules: `getName` -> `name`. - **`isX()` rule:** the property name is the **whole accessor name**, including `is`. `isEnabled()` -> property `isEnabled` (NOT `enabled`). The `is`-prefix rule applies when the accessor **returns `Boolean`/`boolean`** and is named `is...`. ## The setter side The matching setter for an `isEnabled` property is `setEnabled(...)` — the `is` is dropped and replaced with `set`. So: ```kotlin // Java: boolean isEnabled() / void setEnabled(boolean v) val w = Widget() val on: Boolean = w.isEnabled // calls isEnabled() w.isEnabled = true // calls setEnabled(true) ``` If the setter were named `setIsEnabled(...)` it would NOT pair with the `isEnabled` getter — the names must line up by the JavaBeans rule, so a mismatched setter leaves the property **read-only**. ## Why it matters - Reading code, you'll see `obj.isEnabled` rather than `obj.enabled`; don't 'fix' it. - This is also why the **Kotlin-to-Java direction** matters: a Kotlin `val isEnabled: Boolean` generates a JVM getter named `isEnabled()` (no `get`), keeping symmetry with Java consumers. - Non-Boolean accessors named `isX()` do NOT get the special treatment in the same way — the rule is tied to the boolean return type. ## Common confusion `getEnabled(): Boolean` -> property `enabled`. `isEnabled(): Boolean` -> property `isEnabled`. Same concept, different spelling, driven purely by the accessor name prefix.

  • Java has `boolean isActive()` and `void setIsActive(boolean)`. Is the property read-write?
    No — the setter name doesn't match the JavaBeans pairing (`setActive` is expected), so `isActive` is read-only.
  • How does a Kotlin `val isReady: Boolean` look to Java callers?
    Kotlin generates a getter named `isReady()` (no `get` prefix), mirroring the Java `is` convention.

saying these in an interview costs you the question

  • Saying isEnabled() maps to property 'enabled'
  • Expecting the setter to be setIsEnabled
  • Not knowing the is-rule depends on a Boolean return type
  • Confusing the getX -> x rule with the isX -> isX rule

context