skip to content

What does isPresent mean on a Property, and how does convention() interact with set() and presence?

level: middleimportance: should knowfreq 35%

answer

  1. isPresent = value resolvable, no throw
  2. convention = default until set()
  3. set() overrides convention
  4. convention after set() is a no-op
  5. getOrElse is read-site only

basics

~10 s

isPresent is true when a value can be computed — from an explicit set() or a convention. convention() supplies a default used only if nothing is explicitly set; an explicit set() overrides the convention.

solid answer

~40 s

`isPresent` on a `Provider`/`Property` returns `true` when the value can be resolved without error — i.e., something has supplied it. For a bare `Property` with nothing set, `isPresent` is `false` and `get()` throws. `convention(value)` registers a **default**: it makes the property present (so `isPresent` becomes `true` and `get()` returns the convention) **until** an explicit `set()` overrides it. Order matters in a subtle way: calling `convention()` after a `set()` has no effect, because an explicit value already exists. This lets plugin authors provide sane defaults that consumers can override. Contrast with `getOrElse(default)`, which is only a read-site fallback and does not affect `isPresent` or downstream wiring. Use `convention` for the canonical default of an input and reserve `isPresent` for genuinely optional inputs where you branch on whether the user configured anything.

code

kotlin · 8 lines
kotlin
val outDir = objects.property(String::class)
outerScope@ run {
    outDir.convention("build/out")  // default
    println(outDir.isPresent)       // true
    println(outDir.get())           // build/out
    outDir.set("build/custom")      // user override
    println(outDir.get())           // build/custom
}

go deeper

for a junior

Know isPresent is true/false for whether a value exists, and convention gives a default.

for a middle

Explain that set() overrides convention and that convention makes isPresent true; contrast with getOrElse.

for a senior

Discuss lazy conventions (provider-sourced), the set-then-convention no-op rule, and using isPresent for optional inputs.

for a principal

Define when plugins should ship conventions vs require explicit configuration, and document the override semantics for consuming teams.

## isPresent `isPresent` answers: *can this provider produce a value right now?* It returns a `boolean` and never throws. A freshly created `objects.property(String::class)` with no value and no convention is **absent** (`isPresent == false`), and `get()` on it throws `IllegalStateException`. ## convention() `convention(T)` or `convention(Provider<T>)` registers a **fallback** value: - It makes the property **present** — `isPresent` becomes `true` and `get()` returns the convention value. - It is **overridden** by an explicit `set()`. - It is itself ignored if a `set()` already happened *before* the `convention()` call — convention only fills the gap when no explicit value exists at the time it's consulted. ```kotlin val greeting = objects.property(String::class) greeting.convention("hello") greeting.isPresent // true greeting.get() // "hello" greeting.set("hi") // explicit value wins greeting.get() // "hi" ``` ## Why conventions beat eager defaults A convention is **lazy** and participates in the provider graph, so a convention sourced from another provider stays deferred. It also keeps the "was this explicitly set?" distinction available, unlike pre-assigning a field. ## convention vs getOrElse | | convention(d) | getOrElse(d) | |---|---|---| | Affects isPresent | yes (becomes present) | no | | Visible downstream | yes | no (read-site only) | | Overridden by set() | yes | n/a | Use `convention` to define the default of an input; use `getOrElse` for a local fallback when reading any provider you don't own. ## Optional inputs For a truly optional input, leave no convention and branch: ```kotlin if (extension.licenseHeader.isPresent) { applyHeader(extension.licenseHeader.get()) } ``` This avoids exceptions and expresses "only act if configured".

  • If you call set() and then convention() on the same property, which wins?
    The explicit set() value wins. convention only supplies a value when no explicit value exists, so a convention applied after a set() is effectively ignored.
  • How is convention() different from getOrElse() for defaults?
    convention() sets a default on the property itself: it makes isPresent true and is visible to anything reading the property, and is overridden by set(). getOrElse() only provides a fallback at one read call and doesn't change presence or downstream wiring.

saying these in an interview costs you the question

  • Saying isPresent throws when absent — it returns false.
  • Believing convention() overrides an explicit set().
  • Treating getOrElse as equivalent to convention for shared defaults.

context