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
var, Kotlin’s keyword representing mutable, non-final variables. Once initialized, we’re free to mutate/change the data held by the variable.
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
val keyword works same as the var keyword, but with one key difference the variable is read-only/nonmutable. The use of val is like declaring a new variable in Java with the final keyword.
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
lateinit means late initialization. If you do not want to initialize a variable in the constructor instead you want to initialize it later on and if you can guarantee the initialization before using it, then declare that variable with lateinit keyword. It will not allocate memory until initialized.
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
It means lazy initialization. Your variable will not be initialized unless you use that variable in your code. It will be initialized only once after that we always use the same value.
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
getters are used for getting value of the property. Kotlin internally generates a getter for read-only properties using val. The getter is optional in kotlin. Property type is optional if it can be inferred from the initializer.
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
setters are used for setting value of the property. Kotlin internally generates a default getter and setter for mutable properties using var. Property type is optional if it can be inferred from the initializer.
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…