skip to content

Explain the difference between get(), getOrNull(), and getOrElse() on a Provider, and when each is appropriate.

level: middleimportance: must knowfreq 55%

answer

  1. get() throws on absent
  2. getOrNull() -> null
  3. getOrElse(d) -> fallback d
  4. isPresent to test first
  5. read at execution, not configuration

basics

~20 s

get() returns the value or throws if absent. getOrNull() returns the value or null. getOrElse(default) returns the value or the supplied default. Pick based on whether a missing value is an error or has a fallback.

solid answer

~40 s

All three read a `Provider<T>`'s value lazily but differ on the **absent** case. `get()` returns the value or throws `IllegalStateException` ("No value has been specified...") — use it when the value is mandatory and absence is a real error. `getOrNull()` returns the value or `null` — use it when you want to branch on presence yourself without an exception. `getOrElse(default)` returns the value or a supplied fallback — use it for an inline default when none was configured. There's also `isPresent`, which lets you check first. Crucially, you should **avoid calling any of these during the configuration phase** for inputs that may be set later — reading too early forces resolution before users have finished configuring. Read them during execution (e.g., inside the task action) so deferred wiring works.

code

kotlin · 6 lines
kotlin
val port = project.objects.property(Int::class)
// no value set
port.get()                 // throws IllegalStateException
port.getOrNull()           // null
port.getOrElse(8080)       // 8080
port.isPresent             // false

go deeper

for a junior

Name the three methods and their absent-case behavior (throw / null / default).

for a middle

Map each to a use case and contrast getOrElse with convention(); mention isPresent.

for a senior

Stress resolution timing — read at execution, not configuration — and the config-cache implications of eager reads.

for a principal

Codify guidelines (convention for defaults, get() only at execution) as conventions for the team's shared plugins to keep builds lazy and cacheable.

## The three readers Every `Provider<T>` (and therefore every `Property<T>`) exposes the same value-reading API. They diverge only when **no value is present**: | Method | Value present | Value absent | |---|---|---| | `get()` | returns `T` | throws `IllegalStateException` | | `getOrNull()` | returns `T` | returns `null` | | `getOrElse(d)` | returns `T` | returns `d` | And `isPresent` returns a `boolean` you can test without triggering a throw. ## When to use which - **`get()`** — the value is required and missing it is a programming/usage error. Common inside a task action for a `@Input` that the user *must* supply. The thrown message is descriptive and points to the property. - **`getOrNull()`** — you want to handle absence with your own control flow (e.g., skip a step) and `null` is a meaningful "not configured". - **`getOrElse(default)`** — you have a sensible inline fallback. Note: prefer `convention(default)` on the `Property` itself for defaults that should also be visible to downstream wiring; `getOrElse` is a *local* fallback only at the read site. ## Timing matters These methods **force resolution**. If you call `provider.get()` in the configuration block of a plugin, you resolve the value *immediately*, defeating laziness and possibly reading before the user finished configuring. The correct place to read is the **execution phase**: ```kotlin tasks.register("greet") { val who = project.objects.property(String::class) who.convention("world") doLast { println("hello, " + who.get()) } // read at execution } ``` ## convention vs getOrElse Both supply a default, but `convention` is set on the `Property` and participates in wiring and presence semantics — `isPresent` is `true` once a convention exists. `getOrElse` only affects that single read. Use `convention` for the canonical default of an input, and `getOrElse` for an ad-hoc fallback when reading any provider.

  • If a Property has a convention but no explicit value, what does isPresent return?
    true. A convention provides a value, so the property is present and get() returns the convention value. The convention only stops applying once an explicit value is set (or it's overridden).
  • Why is calling get() in a plugin's apply() block often a bug?
    apply() runs during configuration, before users finish wiring inputs. Calling get() there resolves the value too early — you may read a missing/default value and you defeat lazy deferral, which can also break configuration-cache compatibility.

saying these in an interview costs you the question

  • Saying getOrNull() throws — it returns null.
  • Using getOrElse as the canonical default instead of convention() on the property.
  • Reading provider values during configuration for inputs set later.

context