lateinit / lazy
An overview of lateinit var, which defers initialization, and the lazy property delegate by lazy, which initializes a value on first access.
Syntax
// lateinit: a variable initialized later (used with non-null var)
lateinit var propertyName: Type
// by lazy: a val initialized on first access
val propertyName: Type by lazy {
// initialization logic
value
}
Syntax Reference
| Syntax | Description |
|---|---|
| lateinit var variableName: Type | Allows you to skip initialization at declaration. Accessing the property before it is initialized throws an exception. |
| ::propertyName.isInitialized | Checks whether a lateinit variable has been initialized. |
| val variableName by lazy { } | Executes the lambda on first access and caches the result as the property value. |
| by lazy(LazyThreadSafetyMode.NONE) { } | Lazy initialization with thread safety disabled. Intended for single-threaded use. |
Sample Code
class DatabaseManager {
// lateinit: a property assigned after construction
lateinit var connectionString: String
fun connect(url: String) {
connectionString = url
}
fun status(): String {
// isInitialized checks whether the property has been initialized.
return if (::connectionString.isInitialized) {
"Connected: $connectionString"
} else {
"Not connected"
}
}
}
class AppContext {
// by lazy: the lambda runs only on the first access.
val config: Map<String, String> by lazy {
println("Loading configuration...")
mapOf("theme" to "dark", "lang" to "ja")
}
}
fun main() {
val db = DatabaseManager()
println(db.status()) // Not connected
db.connect("jdbc://localhost")
println(db.status()) // Connected: jdbc://localhost
val ctx = AppContext()
// The lambda runs only on the first access.
println(ctx.config["theme"]) // Loading configuration... → dark
println(ctx.config["lang"]) // Lambda does not run again → ja
}
Notes
Use lateinit var when initialization must happen outside the constructor, such as with dependency injection frameworks or test code. Accessing the property before it is initialized throws an UninitializedPropertyAccessException, so use isInitialized to check first if you are unsure. Note that lateinit cannot be used with primitive types such as Int or Boolean.
by lazy is useful when you want to defer an expensive initialization until it is actually needed. Once initialized, the value is cached and the lambda is never executed again. Thread safety is enabled by default.
If you find any errors or copyright issues, please contact us.