Kotlin中带自定义getter、默认setter且无初始化器的属性是否合法?
Great question—let's break this down clearly, since the behavior you're seeing across environments can be confusing.
Short Answer
This code is not actually compliant with Kotlin's official specifications, which is why Android Studio throws the "Property must be initialized" error. The fact that it runs on try.kotlinlang.org is an edge case that only works if you never call the setter—once you try to assign a value to the property, it will crash immediately.
Why the Discrepancy?
Let's unpack the rules behind Kotlin properties:
- When you declare a
varproperty without a custom setter, Kotlin automatically generates a backing field to store the property's value. The default setter's sole job is to update this field. - If you define a custom getter but skip the initializer and never reference
fieldin your getter/setter, the compiler won't create a backing field at all—since there's no value to store in the first place.
Here's the core conflict: your default setter expects a backing field to modify, but none exists. Android Studio catches this inconsistency at compile time (correctly), while try.kotlinlang.org lets you run it only if you never invoke the setter. The getter works because it just returns a hardcoded value, but the setter has nothing to operate on under the hood.
What's the Correct Approach?
Depending on your actual needs, use one of these valid, specification-compliant patterns:
Property with stored value and custom getter
If you need to both store a value and customize how it's retrieved, initialize the backing field explicitly:var testProperty: String = "test" get() = field.uppercase() // Custom getter logic // Default setter is implicit here—no need to write it outRead-only property with custom getter
If you don't need to modify the value (just return a fixed or computed value), usevalinstead ofvar:val testProperty: String get() = "test"Mutable property with custom setter (no backing field)
If you needvarbut don't need to store the value (e.g., just trigger side effects on assignment), define a custom setter that doesn't rely on a backing field:var testProperty: String get() = "test" set(value) { // Handle the assignment here—e.g., log it, update another variable println("Attempted to set value to: $value") }
Wrap-Up
Android Studio's error is the correct behavior here—your original code has a logical contradiction (a setter that needs a backing field that doesn't exist). The try.kotlinlang.org scenario is a false positive that only works in limited circumstances. Stick to the valid patterns above to avoid unexpected crashes or compile errors.
内容的提问来源于stack exchange,提问作者nibarius

