A Deep Dive into Kotlin Property Initialization: lateinit, const, var, val, and lazy

Kotlin’s Properties: Dive into Initialization and differences

Mehdi Taghdisi
6 min readSep 23, 2023

Intro

When it comes to developing Android applications, how you initialize properties, in Kotlin plays a role in determining how your code functions. In this guide, we’ll go into aspects from used var and val to more advanced techniques, like lateinit, const and lazy. By understanding their distinctions and exploring examples you’ll gain the insights needed to make informed decisions and optimize your Android apps. Let's dive into these Kotlin features that can enhance your coding skills.

Understanding var Properties and Mutability

In Kotlin, the var is used to declare mutable properties. Mutable properties can have their values reassigned after their initial assignment. This makes var a flexible choice when you need properties that can change throughout the lifecycle of your Android application.

Usage Example:

Here’s a simple example of declaring and using a var property in a Kotlin class:

We defined a User class with var properties for name and age. We initialize them with default values and then update their values later.

Key Points:

  • var properties are mutable, meaning you can change their values after initialization.
  • They are often used for properties that can change during your Android app’s execution.
  • Be cautious with mutable properties to maintain the desired state and avoid unexpected side effects in your code.

Exploring val Property Initialization

In Kotlin, the val is used to declare immutable properties. Immutable properties have values that cannot be modified after their initial assignment. This makes val an excellent choice for properties that should remain constant throughout the lifecycle of your Android application.

Usage Example:

Here’s an example of declaring and using val properties in a Kotlin class:

class Car(make: String, model: String, year: Int) {
val make: String = make
val model: String = model
val year: Int = year

fun getInfo(): String {
return "Make: $make, Model: $model, Year: $year"
}
}

fun main() {
val myCar = Car("Toyota", "Camry", 2023)
println(myCar.getInfo()
// Uncommenting the line below would result in a compilation error
// myCar.year = 2024
}

We create a Car class with val properties for make, model, and year. These properties are assigned values in the constructor and cannot be modified afterward. Attempting to modify them would result in a compilation error.

Key Points:

  • Val properties are immutable, meaning their values cannot be changed once assigned.
  • They are often used for properties representing constant or unchangeable values.
  • val properties are safe to use when you want to ensure that a property’s value remains constant throughout its lifetime.
val and val in summery

Exploring lateinit Property initialization
In Kotlin, lateinit is a modifier that can be applied to properties. It’s a powerful feature that allows you to defer the initialization of a property until a later point in your code. lateinit is particularly useful when you have properties that can’t be initialized immediately but are guaranteed to have a value before you access them.

Usage Example:

Here’s a simple example of using lateinit in a Kotlin class:

In this example, we declare a username property as lateinit , which means we don’t assign it a value during initialization. Instead, we initialize it later using the initialize function. We also used ::username.isInitialized to check whether the property has been initialized before accessing it.

P.s: If you don’t know about :: in ::username.isInitialized , here is some explanation:
In the code snippet, :: before the username is called the property reference operator in Kotlin. It’s used to refer to a property or member of a class without invoking it.

Key Points:

  • lateinit is used when you have a property that cannot be initialized immediately but will have a value assigned before you use it.
  • It allows you to avoid nullable types and provides a guarantee that the property will not be null when accessed.
  • Be cautious when using lateinit, as accessing an uninitialized property will result in a runtime exception.

Remember you never use something like lateinit val , if you do, you get a compile error because val can not be reassigned.

Compile-time constants with const

The const is used to declare compile-time constants. Constants are values that are known at compile time and cannot be changed at runtime. While const is often used for top-level properties, it has some limitations and specific use cases and is typically used for values that remain constant throughout the application's lifetime.

Usage example:

Here’s a simple example of using const in a Kotlin class:

Key Points:

  • const properties are used for compile-time constants with known values.
  • They are typically declared in companion objects or top-level objects.
  • Reassigning a const property is not allowed, as it’s meant to be a constant value.
const, var, val in summary

Now let's go with lazy Property Initialization

The lazy is a powerful way to initialize properties only when they are first accessed. This can help improve the efficiency of your code by deferring initialization until it’s needed. lazy properties are especially useful when you have expensive or time-consuming initializations that you want to delay until necessary.

The output is like the below, after 2 secs:

Car Information (Before accessing engineType):
Model: Camry, Year: 2023, Engine Type: V6

Accessing engineType...
Engine Type: V6

Car Information (After accessing engineType):
Model: Camry, Year: 2023, Engine Type: V6

We use the lazy delegate for the engineType property of the Car class. The engine type is initialized only when it’s first accessed. We simulate a time-consuming initialization using Thread.sleep to illustrate the benefits of lazy initialization.

Key Points:

  • lazy is used for properties that should be initialized only when first accessed.
  • It can improve efficiency by delaying initialization until necessary.
  • Lazy initialization is thread-safe by default, making it suitable for concurrent environments.
  • Can be only used with the val keyword, so can consider it read-only
lazy, lateinit var, in summary

Comparing lazy and lateinit var Property Initialization

In Kotlin, both lazy and lateinit var are techniques used to defer property initialization. However, they serve different purposes and have distinct characteristics.

Lazy Property Initialization:

  • lazy is used when you want to defer property initialization until it’s first accessed.
  • lazy properties are thread-safe by default, making them suitable for concurrent environments.
  • The initialization code is executed only once when the property is first accessed, and the result is cached for subsequent access.

lateinit var Property Initialization:

  • lateinit var is used when you have a property that cannot be initialized during object construction but will have a value before you access it.
  • lateinit var properties are not thread-safe by default, so you should ensure they are properly initialized before use to avoid runtime exceptions.
  • The property must be explicitly initialized before it’s accessed; otherwise, it will throw an UninitializedPropertyAccessException.

Choosing Between lazy and lateinit var:

  • Use lazy when object creation is expensive and, you want to defer initialization until the property of that object is needed while making sure it is completely thread-safe
  • Use lateinit var when you have a property that will be initialized before it’s accessed and you need to guarantee that it’s not null when accessed.

Overall:

As an Android developer, you are like an artist, knowing your tools enables you to create clean, smooth, and fewer error codes. Just make sure you choose them wisely.
Happy coding! 🎨🚀✨

--

--

Mehdi Taghdisi
Mehdi Taghdisi

Written by Mehdi Taghdisi

ASP.Net, React, React-Native and Android developer, an eager problem solver

No responses yet