How to check if a lateinit variable has been initialized?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Kotlin's lateinit modifier exists for properties that cannot be initialized in the constructor but still should behave like non-null values later. The feature is useful, but it comes with one rule you cannot ignore: reading a lateinit property before assignment throws UninitializedPropertyAccessException.
How lateinit Works
You can apply lateinit only to mutable, non-primitive properties. Kotlin uses it for cases such as dependency injection, view binding, and test setup where a value is guaranteed to arrive later.
This compiles even though token has no initial value. The responsibility shifts to you: initialize it before first use.
Checking Initialization With isInitialized
Kotlin exposes isInitialized on a property reference. That is the standard way to check a lateinit property safely.
This example is runnable and prints a safe message before initialization, then prints the token afterward.
The syntax matters. You are not checking the value directly. You are asking Kotlin about the property reference with this::token.isInitialized.
Scope Rules You Need to Know
isInitialized is only available where the property reference is accessible. In practice, that usually means inside the same class, inside an outer class for an inner property that is visible, or in test code that owns the property.
Trying to check holder::serviceName.isInitialized from unrelated code often fails because the compiler restricts that usage.
When a Nullable Property Is Better
Developers sometimes use lateinit when a nullable type would express the state more honestly. If the value is optional, String? is often clearer than lateinit var String.
This approach avoids property-reference checks and makes the unset state explicit in the type system.
Using lazy for Read-Only Deferred Initialization
If the value should be initialized once and then never reassigned, lazy is a better fit than lateinit.
Here initialization happens automatically on first access, and Kotlin guarantees the property is ready when returned.
A Practical Testing Pattern
lateinit is common in tests because setup methods often assign shared fixtures.
This keeps the test readable while still protecting against accidental early access.
Common Pitfalls
The most common pitfall is assuming lateinit behaves like an optional value. It does not. Access before assignment is a runtime failure, not a null result.
Another mistake is trying to use lateinit on primitive types like Int. Kotlin rejects that because primitives always need a concrete value representation.
A subtler problem is overusing lateinit in domain models. If an object is invalid until several properties are assigned later, the constructor is probably not expressing the real invariants of the type.
Developers also get tripped up by scope. isInitialized is not a universal reflection trick you can call anywhere. It works where the property reference is visible and supported by the compiler.
Summary
- Use
this::property.isInitializedto check whether alateinitproperty has been assigned. - '
lateinitis for mutable, non-null, non-primitive properties.' - Prefer nullable properties when the value is genuinely optional.
- Prefer
lazywhen a value should be computed once on first access. - Treat
lateinitas a delayed guarantee, not as a replacement for good object design.

