var and val in Kotlin: what's the difference? Full breakdown
If you are just starting your journey in Kotlin or coming from other languages (Java, Python, JavaScript), one of the first questions you will ask is why are two keywords needed for declaring variables? Indeed, why complicate things if you can get by with one? The answer lies in the philosophy of the language: Kotlin was created to make code safer, clearer, and more predictable. And the difference between var and val is not a whim, but a powerful tool for managing state.
Let's figure out with examples when to use var and when to use val, and why this is important for your code.
What are var and val? Basic definitions
Let's start with the simplest.
var(from English variable) — a mutable variable. You can reassign a new value to it as many times as you like.val(from English value) — an immutable reference (read-only). After initialization, you cannot change its value. It is analogous tofinalin Java orconstin JavaScript (with some caveats).
Here is the simplest example:
fun main() { var x = 10 x = 20 // OK: var can be changed
val y = 30 // y = 40 // Compilation error: val cannot be reassigned
println("x = $x, y = $y")}Everything seems obvious, but the devil, as always, is in the details.
The main difference: mutability of reference vs mutability of object
This is where confusion often arises. val guarantees that the reference to an object will not change, but it does not guarantee the immutability of the object itself.
Let's break it down with a list example:
fun main() { val numbers = mutableListOf(1, 2, 3) // numbers = mutableListOf(4, 5, 6) // Error: val cannot be reassigned
numbers.add(4) // But this is allowed! We are changing the contents of the object numbers[0] = 100 // And this is also allowed
println(numbers) // [100, 2, 3, 4]}Notice: we declared numbers as val, but we can freely add and change elements. Why? Because val protects only the reference itself (the variable numbers), not the object it points to.
If you want complete immutability, you need to use immutable collections (listOf, mapOf, setOf) and val simultaneously.
fun main() { val immutableNumbers = listOf(1, 2, 3) // immutableNumbers.add(4) // Error: listOf returns an immutable list // immutableNumbers[0] = 100 // Error}This is an important point that is often asked in interviews. Remember: val ≠ immutable object.
When to use var and when to use val?
The golden rule of Kotlin: use val everywhere possible, and var only when it is truly necessary. Why?
- Safety. The fewer mutable variables, the less chance of accidentally changing a value in an unexpected place. This is especially important in multithreaded programming.
- Readability. When you see
val, you immediately know that the value will not change. This simplifies understanding the code. - Functional style. Kotlin encourages functional programming, where immutability is one of the key principles.
Here is an example where var is justified:
fun main() { var counter = 0 while (counter < 10) { println("Counter: $counter") counter++ // The counter must change }}And here is an example where var is a bad practice and can be replaced