Kotlin var, val, lateinit, lazy, getters & setters

Kotlin is a very concise language with handy mutability and immutability features. Let’s see how variable declaration and initialization works in kotlin with those features.

var

Let’s take a look at how this works:

var myVariable = 1

Behind the scenes, myVariable initializes with the Int data type.

Although Kotlin uses type inference, which means we also have the option to specify the data type when we initialize the variable like below:

var myVariable: Int = 1

Variables declared as one data type and then initialized with a value of the wrong type will result in an error.

var myVariable: Int = b //ERROR! as b is different type

val

For example, in Kotlin:

val name: String = "Kotlin"

Whereas in Java:

final String name = "Kotlin";

val variables must be assigned at declaration, or in a Classconstructor.

class Address(val street: String) {

val name: String = "Kotlin"

}

lateinit

For example:

private lateinit var myViewModel: MyViewModel

Then initialize somewhere in your MyViewModel class

myViewModel = MyViewModel()

You cannot use val for lateinit variable as it will be initialized later on. Also you must guarantee that you are initializing the variable before using the variable otherwise it will throw exception at runtime. You cannot use lateinit for primitive type properties like Int, Long etc.

Accessing a lateinit property before it has been initialized throws a special exception that clearly identifies the property being accessed and the fact that it hasn't been initialized.

lazy

lazy() is a function that takes a lambda and returns an instance of lazy which can serve as a delegate for implementing a lazy property: the first call to get() executes the lambda passed to lazy() and remembers the result, subsequent calls to get() simply return the remembered result.

val test: String by lazy {
val testString = "some value"
}

lateinit or lazy

If variable are mutable (i.e. might change at a later stage) use lateinit

lateinit var can be initialized from anywhere the object is seen from.

lazy can only be used for val properties, whereas lateinit can only be applied to var because it can’t be compiled to a final field, thus no immutability can be guaranteed.

If its only meant to initialized once and shared by all, and it’s more internally set (dependent on variable internal to the class), then use lazy.

getter

val inferredType = 1 // has type Int and a default getter

If we define a custom getter, it will be called every time we access the property like below:

val updateLiveData: LiveData<Boolean>
get() = isUpdateLiveData

setter

var initialized = 1 // has type Int, default getter and setter

If we define a custom setter, it will be called every time we assign a value to the property. A custom setter looks like this:

var stringRepresentation: String
get() = this.toString()
set(value) {
setDataFromString(value)
// parses the string and assigns values to other properties
}

By convention, the name of the setter parameter is value, but you can choose a different name if you prefer.

You can make setter as private so that outsider can’t set the value.

var setterVisibility: String = "abc"
private set // the setter is private and default implementation

Feel free to share your thoughts or feedbacks. Happy Kotlin…

--

--

Senior Android Engineer @Delivery Hero | Android developer | Kotlin lover | Flutter explorer | Problem Solver

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Md Ali Hossain

Senior Android Engineer @Delivery Hero | Android developer | Kotlin lover | Flutter explorer | Problem Solver