Val vs Var in Kotlin

In Kotlin, val and var are used to declare variables, but they behave differently after assignment. Use val when the variable reference should not be reassigned. Use var when the variable value must change later.

</>
Copy
var hours = 20
val hoursInDay = 24

The difference is simple: var creates a mutable variable, while val creates a read-only variable. Kotlin encourages val by default because it makes code easier to reason about and reduces accidental reassignment.

Meaning of val and var in Kotlin variables

Var means variable. The value stored in a var declaration can be changed after the first assignment.

Val means value. A val declaration is read-only after it receives a value. You cannot assign a new value to the same val variable. However, when a val holds a reference to a mutable object, the object itself may still allow changes to its internal properties.

Kotlin keywordCan be reassigned?Typical use
valNoValues that should stay the same reference after assignment
varYesValues that must be updated during program execution

Assign and change value of Var for a basic data type

We shall look into an example where we shall assign some data to val and var, and try to change the values they hold.

Kotlin Program – example.kt

</>
Copy
fun main(args: Array<String>) {
    var numberOfHoursPassed = 3
    print("Number Of Hours Passed for the day : "+numberOfHoursPassed)
    // after ten hours
    numberOfHoursPassed = 13
    print("\nNumber Of Hours Passed for the day : "+numberOfHoursPassed)
}

Output

Number Of Hours Passed for the day : 3
Number Of Hours Passed for the day : 13

The value of a var could be changed.

Here, numberOfHoursPassed is first assigned 3. Later, the same variable is reassigned to 13. This is valid because the variable is declared using var.

Assign and change value of Val for a basic data type

We shall look into an example where we shall assign some data to val and var, and try to change the values they hold.

Kotlin Program – example.kt

</>
Copy
fun main(args: Array<String>) {
    val numberOfHoursInDay = 24
    print("Number Of Hours Passed for the day : "+numberOfHoursInDay)
    // after an hour
    numberOfHoursInDay = 25
    print("\nNumber Of Hours Passed for the day : "+numberOfHoursInDay)
}

Output

Error:(5, 5) Kotlin: Val cannot be reassigned

Kotlin compilation Error – Val cannot be reassigned occurs.

The error happens because numberOfHoursInDay is declared with val. Once the value 24 is assigned, the same variable name cannot be assigned another value.

Kotlin val is read-only, not always a compile-time constant

A common confusion is to treat every val as a constant. A val is read-only after assignment, but its value may still be calculated while the program runs. For a compile-time constant, Kotlin provides const val, which is allowed only for certain top-level or object-level primitive and String values.

</>
Copy
const val MAX_USERS = 100

fun main() {
    val currentUserCount = getUserCount()
    println(currentUserCount)
}

fun getUserCount(): Int {
    return 42
}

In this example, MAX_USERS is a compile-time constant. The currentUserCount variable is read-only after assignment, but its value comes from a function call at runtime.

Assign and change properties of Val object

We shall look into an example where we shall declare an object to val and try changing the values of its properties.

Kotlin Program – example.kt

</>
Copy
fun main(args: Array<String>) {
    val book = Book("The Last Sun",250)
    print(book)
    book.name = "Incredible Hulk"
    print("\n"+book)
}
 
data class Book(var name: String = "", var price: Int = 0)

Output

Book(name=The Last Sun, price=250)
Book(name=Incredible Hulk, price=250)

We have used Data Class in Kotlin to realize properties of an object. The properties of a val object could be changed.

This works because book itself is read-only, but the name property inside the Book object is declared with var. Kotlin prevents this statement: book = Book("Another Book", 300). It does not prevent book.name = "Incredible Hulk", because the object exposes a mutable property.

Val with mutable and immutable collections in Kotlin

The same idea applies to collections. A val list reference cannot be reassigned, but the list may still be mutable if its type supports mutation.

</>
Copy
fun main() {
    val numbers = mutableListOf(1, 2, 3)
    numbers.add(4)
    println(numbers)
}
[1, 2, 3, 4]

The variable numbers cannot point to another list after assignment, but the existing mutable list can still receive new elements. To avoid this, use immutable collection interfaces where possible.

</>
Copy
fun main() {
    val numbers = listOf(1, 2, 3)
    // numbers.add(4) // Not allowed, because listOf returns a read-only List
}

When to use val and when to use var in Kotlin

Prefer val when a variable does not need reassignment. Change it to var only when the value must be updated later, such as counters, loop state, user input that changes, or values calculated step by step.

  • Use val for fixed values such as hoursInDay, configuration values, and references that should not be replaced.
  • Use var for changing values such as score, attempts, currentIndex, or form fields that are edited.
  • Use const val only when you need a compile-time constant and the declaration satisfies Kotlin rules.
  • Use immutable object properties and read-only collections when you want stronger immutability than a simple val reference.

In Android Kotlin code, this difference is especially useful in state handling. For example, a screen title may be a val, while a changing counter or input text may be a var depending on how the state is managed.

Common mistakes with Kotlin val and var

  • Using var by habit: If the value is not reassigned, use val.
  • Expecting val to freeze an object: val prevents reassignment of the reference, not all mutation inside the referenced object.
  • Calling every val a constant: A val is read-only after assignment. A const val is a compile-time constant.
  • Confusing read-only List with mutableListOf: A val holding mutableListOf() can still be modified through list operations.

Quick decision rule for val vs var in Kotlin

Start with val. If the compiler or your program logic shows that the variable must be reassigned, change it to var. This keeps the code clearer and limits accidental updates.

QA checklist for this Kotlin val vs var tutorial

  • Confirm that every explanation separates reassignment from object mutation.
  • Check that val, var, and const val are not described as the same concept.
  • Verify that output blocks show only program output or compiler messages.
  • Make sure each Kotlin example uses the correct keyword for the behavior being demonstrated.
  • Keep internal links relevant to Kotlin basics and avoid changing existing linked URLs.

FAQs on val vs var in Kotlin

Why should I use val instead of var in Kotlin?

Use val when reassignment is not required. It makes the variable read-only after assignment and helps prevent accidental value changes in the rest of the code.

What is the difference between val and var in Kotlin?

val cannot be reassigned after a value is assigned. var can be reassigned later. Both can use type inference, so Kotlin can often determine the type automatically.

Does val make an object immutable in Kotlin?

No. val makes the variable reference read-only. If the referenced object has mutable properties or mutable collection functions, those internal values may still change.

What is var in Kotlin used for?

var is used for values that must change during execution, such as counters, scores, indexes, editable form values, or temporary state.

Is val the same as const val in Kotlin?

No. val is read-only after assignment. const val is a compile-time constant and has stricter rules about where and how it can be declared.

Conclusion

In this Kotlin Tutorial, we have learnt about Val vs Var in Kotlin that var could be changed at any level. Whereas val once assigned, could not be changed, but its properties could be changed.

The practical rule is to use val first and use var only when reassignment is part of the required logic. For deeper immutability, also choose immutable properties, immutable collection types, and data structures that do not expose mutation.