Question
In Kotlin, what is the exact difference between var and val?
I read the Kotlin documentation about properties and fields, which says that a read-only property declaration:
- starts with
valinstead ofvar - does not allow a setter
However, the documentation also shows code like this:
fun copyAddress(address: Address): Address {
val result = Address() // there's no 'new' keyword in Kotlin
result.name = address.name // accessors are called
result.street = address.street
// ...
return result
}
This confused me because result is declared with val, but its properties are still being changed.
So:
- What is the exact difference between
varandvalin Kotlin? - Why does Kotlin need both?
- Why is it valid to modify
result.nameandresult.streetwhenresultitself is declared withval?
Short Answer
By the end of this page, you will understand that val means the reference cannot be reassigned, while var means it can. You will also see why a val object can still have mutable internal properties, how this differs from full immutability, and how Kotlin developers use val and var in real code.
Concept
In Kotlin, val and var describe whether a variable or property reference can be reassigned.
Core idea
val= read-only referencevar= mutable reference
That means:
val name = "Ava"
// name = "Liam" // not allowed
var city = "Paris"
city = "Rome" // allowed
What val really means
A val does not mean the object itself is deeply immutable.
It only means that the variable now always points to the same object.
If that object has mutable properties, those properties can still change.
For example:
class Address {
var name: String = ""
var street: String = ""
}
val result = Address()
result.name = "Sam" // allowed
result.street =
Mental Model
Think of a variable as a label attached to a box.
valmeans the label must stay attached to the same box.varmeans you can move the label to a different box later.
Now think about the contents of the box.
Even if the label is fixed (val), the contents inside the box may still be changed.
Analogy
val box = Address()
This means:
- you must keep using the same box
- but you may still put different things inside it, if the box allows that
So:
box.name = "Alice"
changes the contents of the box.
But:
box = Address()
tries to replace the entire box, which val does not allow.
Easy rule to remember
valprotects the referencevarallows changing the reference- object mutability depends on the object's own properties, not just on or
Syntax and Examples
Basic syntax
val x = 10
var y = 20
xcannot be reassignedycan be reassigned
Example 1: Primitive-like values
val age = 25
// age = 26 // error
var score = 100
score = 120 // okay
Example 2: Object references
class User {
var name: String = ""
}
val user = User()
user.name = "Maya" // okay
// user = User() // error
Explanation
useris aval, so it must keep pointing to the sameUserobject.nameis a property inside , so it can change.
Step by Step Execution
Consider this code:
class Address {
var name: String = ""
var street: String = ""
}
fun copyAddress(address: Address): Address {
val result = Address()
result.name = address.name
result.street = address.street
return result
}
Step-by-step
1. A new Address object is created
val result = Address()
- Kotlin creates a new
Addressinstance. resultstores a reference to that object.- Because
resultisval, that reference cannot later point to anotherAddress.
2. The name property is copied
result.name = address.name
Real World Use Cases
1. Safer local variables
Most local variables do not need reassignment.
val response = api.getUser()
val parsed = parseUser(response)
Using val makes code easier to reason about because you know those names will not suddenly point somewhere else later.
2. Mutable app state where needed
Sometimes reassignment is required.
var currentPage = 1
currentPage += 1
This is a good use of var because the value is expected to change.
3. Working with mutable objects
You often keep one reference fixed while changing its contents.
val cart = mutableListOf("Book")
cart.add("Pen")
cart.add("Notebook")
cart is still the same list reference, but the list contents change.
4. Domain models with immutable fields
For data you do not want changed accidentally:
data ( id: String, total: )
Real Codebase Usage
In real Kotlin projects, developers usually prefer val by default and switch to var only when mutation is necessary.
Common patterns
Prefer val for local variables
val user = repository.findById(id)
val dto = user.toDto()
return dto
This reduces accidental reassignment.
Use var for changing state
var retries = 0
while (retries < 3) {
retries++
}
Use immutable data models when possible
data class User(val id: Int, val name: String)
When data must change, Kotlin code often creates a new object instead of mutating the old one.
data class User( id: , name: String)
user = User(, )
updatedUser = user.copy(name = )
Common Mistakes
1. Thinking val means fully immutable
This is the most common mistake.
val numbers = mutableListOf(1, 2, 3)
numbers.add(4) // allowed
numbers is read-only as a reference, but the list object is mutable.
How to avoid it
Check both:
- is the reference
valorvar? - is the object itself mutable or immutable?
2. Confusing property mutation with variable reassignment
Broken mental model:
val user = User()
user.name = "Lee" // some beginners expect error here
This is valid if name is a mutable property.
How to avoid it
Remember: user.name = ... changes the object, not the user reference.
3. Using var everywhere
Comparisons
val vs var
| Feature | val | var |
|---|---|---|
| Can be reassigned? | No | Yes |
| Has getter? | Yes | Yes |
| Has setter? | No | Yes |
| Best default choice? | Yes | Only when needed |
| Guarantees object immutability? | No | No |
Reference mutability vs object mutability
| Situation | Allowed? | Why? |
|---|
Cheat Sheet
Quick rules
val= cannot reassign the variable/propertyvar= can reassign the variable/propertyvaldoes not automatically make the object immutable- A
valproperty has a getter only - A
varproperty has a getter and setter
Basic syntax
val a = 10
var b = 20
Object example
val user = User()
user.name = "Kai" // okay if name is var
// user = User() // error
Class property example
class Example {
val x = 1
var y = 2
}
xcannot be assigned after initializationycan be changed later
FAQ
Why can I change properties of a val object in Kotlin?
Because val only prevents reassigning the reference. If the object has mutable (var) properties, those properties can still be changed.
Is val the same as immutable in Kotlin?
No. val means read-only reference, not deep immutability.
Is val similar to final in Java?
Yes, for references it is very similar. A val reference cannot be pointed to another object after assignment.
Should I always use val instead of var?
Use val by default. Change to var only when your logic needs reassignment.
Can a class have both val and var properties?
Yes. This is very common. Some fields stay fixed, while others are allowed to change.
Why does Kotlin provide both val and ?
Mini Project
Description
Build a small Kotlin program that demonstrates the difference between changing a reference and changing the contents of an object. This helps make the val vs var distinction concrete using a simple profile model.
Goal
Create a program that shows: a val reference can keep the same object while its mutable properties change, and a var reference can be reassigned to a different object.
Requirements
- Create a class with at least one
varproperty and onevalproperty. - Declare one object using
valand modify only its mutable property. - Declare another object using
varand reassign it to a new instance. - Print the results so the difference is visible.
Keep learning
Related questions
Android AlarmManager Example: Scheduling Tasks with AlarmManager
Learn how to use Android AlarmManager to schedule tasks, set alarms, and handle broadcasts with a simple beginner example.
Can You Extend a Data Class in Kotlin? Inheritance, Limits, and Better Alternatives
Learn why Kotlin data classes cannot be extended, what causes the component function clash, and which alternatives to use instead.
Difference Between List and Array in Kotlin
Learn the difference between List and Array in Kotlin, including mutability, size, APIs, performance, and when to use each one.