Properties, lazy & lateinit Flashcards
KOTLIN › Language Idioms
- What is the difference between val, var, and const val?
- val is read-only (getter only, assigned once at runtime); var is mutable (getter and setter). const val is a compile-time constant: top-level/object/companion only, String or primitive, no custom getter, and its value is inlined into call sites.
- When would you use lazy versus lateinit?
- Use lazy for a val whose value is expensive and computed once on first access (thread-safe by default, cached). Use lateinit for a non-null var you must assign later (e.g. DI or onCreate), where the type is a non-primitive object reference.
- Why can't lateinit be used with primitives or nullable types?
- lateinit signals uninitialized state using a null sentinel under the hood, so the type must be a non-null reference type. Primitives have no null, and a nullable type could just be initialized to null instead.
- How do you safely check whether a lateinit property has been set?
- Use the property reference: if (this::name.isInitialized). It returns true once assigned; accessing the property before assignment throws UninitializedPropertyAccessException. isInitialized is only available where the property is in scope.
- What is a backing field and when is one generated?
- A backing field is the actual storage behind a property, referenced via the field keyword inside accessors. It is generated only when the property uses a default accessor or an accessor that references field; purely computed properties (custom get with no field) have no backing field.
- What thread-safety modes does lazy support and what is the default?
- SYNCHRONIZED (default) locks so only one thread computes the value; PUBLICATION lets multiple threads race but the first result published wins; NONE skips synchronization for single-threaded access. Pass via lazy(mode) { ... }.
- What is the backing-property pattern and why use it?
- Expose a read-only public property backed by a private mutable one, conventionally named with a leading underscore: private val _items = mutableListOf<T>(); val items: List<T> get() = _items. It lets internal code mutate while external callers see an immutable view.
- How do you restrict a setter's visibility while keeping the getter public?
- Declare the property public and annotate only the setter, e.g. var balance: Int = 0; private set. Outside code can read it but only the class can write it. You can also give the setter a custom body.
- Can lateinit be declared in a primary constructor or have a custom getter?
- No. lateinit cannot appear in the primary constructor and cannot have custom get/set. It must be a var, non-null, non-primitive, declared as a class member, top-level, or local variable.