Skip to content

/compare/kotlin/val-vs-var

Kotlin val vs var: read-only vs mutable variables

The commands on this page have not been executed by our verification runner yet.updated
tool
Kotlin
compares
val vs var

val declares a read-only variable: it is assigned exactly once and cannot be reassigned. var declares a mutable variable that can be reassigned any number of times. Use val by default and switch to var only when the value really has to change; reassigning a val is a compile error.

kotlin
val name = "Ada"     // read-only
var count = 0        // mutable
count += 1           // OK
// name = "Grace"    // compile error: a val cannot be reassigned

Side by side

valvar
ReassignmentNot allowed after initialisationAllowed
Late initialisationCan be assigned once later (val x: Int; x = 1)Can be assigned at any time
As a class propertyGenerates a getter onlyGenerates a getter and a setter
Object it points toCan still be mutable (e.g. a MutableList)Can be mutable or not
Compile-time constantconst val (top level or in an object, primitives and String)Not possible
Thread safetyReference is safe to share once setNeeds synchronisation if shared

val is a read-only reference, not an immutable object

kotlin
val items = mutableListOf(1, 2)
items.add(3)                 // OK: the list changes, the reference does not
// items = mutableListOf()   // not allowed: reassignment

val fixed = listOf(1, 2)     // read-only List interface: no add()

For data that must not change, combine val with read-only types (List, Map, Set) or immutable data classes whose properties are all val.

Properties

kotlin
class User(val id: Int, var email: String)

val u = User(1, "a@example.com")
u.email = "b@example.com"    // var property: has a setter
// u.id = 2                  // val property: no setter

A val property can still return different values if it has a custom getter (val isEmpty get() = size == 0), so val means "no setter", not "constant".

const val

const val defines a compile-time constant, inlined by the compiler. It is allowed only at top level, in an object or a companion object, and only for primitive types and String:

kotlin
const val MAX_RETRIES = 3

Sources