386

What is the difference between var and val in Kotlin?

I have gone through this link:

KotlinLang: Properties and Fields

As stated on this link:

The full syntax of a read-only property declaration differs from a mutable one in two ways: it starts with val instead of var and does not allow a setter.

But just before there is an example which uses a setter.

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
}

What is the exact difference between var and val?

Why do we need both?

This is not a duplicate of Variables in Kotlin, differences with Java: 'var' vs. 'val'? as I am asking about the doubt related to the particular example in the documentation and not just in general.

2240
  • 1,547
  • 2
  • 12
  • 30
Akshar Patel
  • 8,998
  • 6
  • 35
  • 50
  • 8
    `result` can not be changed to refer to a different instance of `Address`, but the instance it refers to can still be modified. The same would be true in Java if you had a `final Address result = new Address();` – Michael May 26 '17 at 11:13
  • refer this http://android-kotlin-beginners.blogspot.in/2018/02/the-var-val-of-kotlin.html – Anam Ansari Feb 01 '18 at 16:14
  • Came here for the answer because the Kotlin website that first describes variables was too dumb to mention it there: https://kotlinlang.org/docs/reference/basic-syntax.html – Johann Nov 14 '18 at 17:43

32 Answers32

331

In your code result is not changing, its var properties are changing. Refer comments below:

fun copyAddress(address: Address): Address {
    val result = Address() // result is read only
    result.name = address.name // but not their properties.
    result.street = address.street
    // ...
    return result
}

val is same as the final modifier in java. As you should probably know that we can not assign to a final variable again but can change its properties.

Jayson Minard
  • 84,842
  • 38
  • 184
  • 227
Sachin Chandil
  • 17,133
  • 8
  • 47
  • 65
  • 1
    val and var in function and classes or in primary constructor have different meaning? –  May 27 '17 at 14:45
  • 3
    @Nothing No, everywhere its same. – Sachin Chandil May 27 '17 at 14:47
  • But when I declare variable with var in the class it required initialization because of it declare the property. But in the function it not required initialization why? –  May 27 '17 at 16:59
  • Because when class loads into the memory, its properties also gets evaluated. But in function variables are evaluated when function code is executed. – Sachin Chandil May 27 '17 at 17:03
  • Its mean inside the function or inside the class both keyword `val` and `var` are used to declare the properties? not variable? –  May 27 '17 at 17:20
  • I am confused by custom getters, example: `val size get() = someList.size` then the value of the val property changes. How is this reconciled with all the answers to this question? – Adam May 03 '19 at 08:31
  • @Adam its same as creating a final variable and in getter return something else. – Sachin Chandil May 03 '19 at 09:29
  • maybe a bit, but say in java you would never create the final variable to begin with, you would just write the getter. Why would kotlin allow you to do this on ```val```why not use something else like some construction with ```var``` instead – Adam May 03 '19 at 11:23
  • but how come both var and val works with the iterators? like both val iterator = collection.iterator() and var iterator = collection.iterator() both are correct ! Here iterator is not changing but its next is changing.Any comments? – Raulp Feb 03 '20 at 14:49
  • This answer is only correct for local variables, not properties. A `val` property might be mutable if it has a custom-getter, and it might be non-final, if it's marked open (final has a different meaning for local variables and for member properties). – Tenfour04 Apr 02 '20 at 19:47
190

val and var both are used to declare a variable.

var is like general variable and it's known as a mutable variable in kotlin and can be assigned multiple times.

val is like Final variable and it's known as immutable in kotlin and can be initialized only single time.

For more information what is val and var please see below link

http://blog.danlew.net/2017/05/30/mutable-vals-in-kotlin/

Community
  • 1
  • 1
Patel Pinkal
  • 8,984
  • 4
  • 28
  • 50
29

variables defined with var are mutable(Read and Write)

variables defined with val are immutable(Read only)

Kotlin can remove findViewById and reduce code for setOnClickListener in android studio. For full reference: Kotlin awesome features

value of mutable variables can be changed at anytime, while you can not change value of immutable variables.

where should I use var and where val ?

use var where value is changing frequently. For example while getting location of android device

var integerVariable : Int? = null

use val where there is no change in value in whole class. For example you want set textview or button's text programmatically.

val stringVariables : String = "Button's Constant or final Text"
user6435056
  • 717
  • 6
  • 5
  • 22
    "Kotlin can remove findViewById and reduce code for setOnClickListener in android studio. For full reference: Kotlin awesome features" How is this relevant to the question asked? – denvercoder9 Dec 04 '17 at 12:25
  • 8
    val variables are not necessarily immutable. They are final -- only the reference is immutable -- but if the object stored in the val is mutable, the object is mutable regardless of whether it is assigned via val or var. – Travis Jun 29 '18 at 21:59
  • 1
    i don't see the point of introducing two new keywords while it could be done much better understandably previously in Java – ruben Dec 08 '18 at 21:45
20

val use to declare final variable. Characteristics of val variables

  1. Must be initialized
  2. value can not be changed or reassign enter image description here

var is as a general variable

  1. We can initialize later by using lateinit modifier

    [lateinit also use for global variable we can not use it for local variable]

  2. value can be changed or reassign but not in global scope

enter image description here

val in kotlin is like final keyword in java

17

val is immutable and var is mutable in Kotlin.

Samir Mangroliya
  • 39,918
  • 16
  • 117
  • 134
14

You can easily think it as:

var is used for setter (value will change).

val is used for getter (read-only, value won't change).

Ling Boo
  • 159
  • 5
14
+----------------+-----------------------------+---------------------------+
|                |             val             |            var            |
+----------------+-----------------------------+---------------------------+
| Reference type | Immutable(once initialized  | Mutable(can able to change|
|                | can't be reassigned)        | value)                    |
+----------------+-----------------------------+---------------------------+
| Example        | val n = 20                  | var n = 20                |
+----------------+-----------------------------+---------------------------+
| In Java        | final int n = 20;           | int n = 20;               |
+----------------+-----------------------------+---------------------------+

Reference

Joby Wilson Mathews
  • 10,528
  • 6
  • 54
  • 53
13

Simply, var (mutable) and val (immutable values like in Java (final modifier))

var x:Int=3
x *= x

//gives compilation error (val cannot be re-assigned)
val y: Int = 6
y*=y
huseyin
  • 1,367
  • 16
  • 19
12

If we declare variable using val then it will be read-only variable. We cannot change it's value. It's like final variable of Java. It's immutable.

But if we declare variable using var then it will be a variable which we can read or write. We can change it's value. It's mutable.

data class Name(val firstName: String, var lastName: String)

fun printName(name: Name): Name {
    val myName = Name("Avijit", "Karmakar") // myName variable is read only
    // firstName variable is read-only. 
    //You will get a compile time error. Val cannot be reassigned.
    myName.firstName = myName.firstName
    // lastName variable can be read and write as it's a var.
    myName.lastName = myName.lastName
    return myName
}

val cannot be initialized lately by the keyword lateinit but non-primitive var can be initialized lately by the keyword lateinit.

Avijit Karmakar
  • 8,890
  • 6
  • 44
  • 59
  • val and var in function and classes or in primary constructor have different meaning? –  May 27 '17 at 14:46
12

Basically

  • var = variable, so it can change
  • val = value, so it can not change.
Ali
  • 2,702
  • 3
  • 32
  • 54
Bharat Sonawane
  • 162
  • 3
  • 10
10

In Kotlin val is a read-only property and it can be accessed by a getter only. val is immutable.

val example :

val piNumber: Double = 3.1415926
    get() = field

However, var is a read-and-write property, so it can be accessed not only by a getter but a setter as well. var is mutable.

var example :

var gravity: Double = 9.8
    get() = field
    set(value) { 
        field = value 
    }    

If you try to change an immutable val, IDE will show you error :

fun main() {    
    piNumber = 3.14          // ERROR
    println(piNumber)
}

// RESULT:   Val cannot be reassigned 

But a mutable var can be changed :

fun main() {    
    gravity = 0.0
    println(gravity)
}

// RESULT:   0.0
Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
10

Comparing val to a final is wrong!

vars are mutable vals are read only; Yes val cannot be reassigned just like final variables from Java but they can return a different value over time, so saying that they are immutable is kind of wrong;

Consider the following

var a = 10
a = 11 //Works as expected
val b = 10
b = 11 //Cannot Reassign, as expected

So far so Good!

Now consider the following for vals

val d
  get() = System.currentTimeMillis()

println(d)
//Wait a millisecond
println(d) //Surprise!, the value of d will be different both times

Hence, vars can correspond to nonfinal variables from Java, but val aren't exactly final variables either;

Although there are const in kotlin which can be like final, as they are compile time constants and don't have a custom getter, but they only work on primitives

Vishal Ambre
  • 403
  • 4
  • 9
  • Interesting example. I never thought of using a `val` in this way: since I try to use Kotlin as immutably as possible, it never occurred to me to even try using a stateful getter for a property marked `val`. – Sebastian Jan 16 '23 at 08:22
6

var is like a general variable and can be assigned multiple times and is known as the mutable variable in Kotlin. Whereas val is a constant variable and can not be assigned multiple times and can be Initialized only single time and is known as the immutable variable in Kotlin.

Val: Assigned once (Read only)

Var: Mutable

example : define a variable to store userId value:

val userId = 1

if we are trying to change the variable userId you will get Error message

userId = 2
error: val cannot be reassigned // Error message!

Let’s create a new variable to store the name of the user:

var userName = "Nav"

if you want to reassign the value of userName you can easily do this because var is mutable

userName = "Van"

and now the value of userName is "Van".

For more information visit this: https://medium.com/techmacademy/kotlin-101-val-vs-var-behind-the-scenes-65d96c6608bf

Naveen kumar
  • 111
  • 1
  • 4
  • constant variable is an oxymoron. "read-only" or "immutable" are better words to describe val – Katana Mar 22 '22 at 17:58
5

Value to val variable can be assigned only once.

val address = Address("Bangalore","India")
address = Address("Delhi","India") // Error, Reassigning is not possible with val

Though you can't reassign the value but you can certainly modify the properties of the object.

//Given that city and country are not val
address.setCity("Delhi") 
address.setCountry("India")

That means you can't change the object reference to which the variable is pointing but the underlying properties of that variable can be changed.

Value to var variable can be reassigned as many times as you want.

var address = Address("Bangalore","India")
address = Address("Delhi","India") // No Error , Reassigning possible.

Obviously, It's underlying properties can be changed as long as they are not declared val.

//Given that city and country are not val
address.setCity("Delhi")
address.setCountry("India")
Saurabh Padwekar
  • 3,888
  • 1
  • 31
  • 37
4

Do you need to change a variable or set it permanently?

  • A good example if it is something like val pi5places = 3.14159 you would set it as val. Is there a possibility that you need to change that variable now or later, then you would set it as var.

  • For example : The color of a car, can be var colorCar = green. Later you can change that colorCar = blue, where as a val, you can not.

  • Responses here regarding mutable and immutable is fine, but may be scary if these terms are not well known or just getting into learning how to program.

teckeon
  • 41
  • 2
2

Both variables are used as initialising

  • val like a constant variable, It can be readable, and the properties of a val can be modified.

  • var just like a mutable variable. you can change the value at any time.

Nikhil Katekhaye
  • 2,344
  • 1
  • 18
  • 19
1

Both, val and var can be used for declaring variables (local and class properties).

Local variables:

  1. val declares read-only variables that can only be assigned once, but cannot be reassigned.

Example:

val readonlyString = “hello”
readonlyString = “c u” // Not allowed for `val`
  1. var declares reassignable variables as you know them from Java (the keyword will be introduced in Java 10, “local variable type inference”).

Example:

var reasignableString = “hello”
reasignableString = “c u” // OK

It is always preferable to use val. Try to avoid var as often as possible!

Class properties:

Both keywords are also used in order to define properties inside classes. As an example, have a look at the following data class:

data class Person (val name: String, var age: Int)

The Person contains two fields, one of which is readonly (name). The age, on the other hand, may be reassigned after class instantiation, via the provided setter. Note that name won’t have a corresponding setter method.

s1m0nw1
  • 76,759
  • 17
  • 167
  • 196
1

val like constant variable, itself cannot be changed, only can be read, but the properties of a val can be modified; var just like mutant variable in other programming languages.

suyanlu
  • 109
  • 1
  • 1
  • 4
1

Var means Variable-If you stored any object using 'var' it could change in time.

For example:

fun main(args: Array<String>) {
    var a=12
    var b=13
    var c=12
    a=c+b **//new object 25**
    print(a)
}

Val means value-It's like a 'constant' in java .if you stored any object using 'val' it could not change in time.

For Example:

fun main(args: Array<String>) {
    val a=12
    var b=13
    var c=12
    a=c+b **//You can't assign like that.it's an error.**
    print(a)
}
NHB SOHEL
  • 11
  • 2
1

In short, val variable is final (not mutable) or constant value that won't be changed in future and var variable (mutable) can be changed in future.

class DeliveryOrderEvent(val d : Delivery)
// Only getter

See the above code. It is a model class, will be used for data passing. I have set val before the variable because this variable was used to get the data.

class DeliveryOrderEvent(var d : Delivery)

// setter and getter is fine here. No error

Also, if you need to set data later you need to use var keyword before a variable, if you only need to get the value once then use val keyword

Shaon
  • 2,496
  • 26
  • 27
1

Var is a mutable variable. It is a variable that can be changed to another value. It's similar to declaring a variable in Java.

Val is a read-only thing. It's similar to final in java. A val must be initialized when it is created. This is because it cannot be changed after it is created.

var test1Var = "Hello"
println(test1Var)
test1Var = "GoodBye"
println(test1Var)
val test2Val = "FinalTestForVal";
println(test2Val);
Marcus Thornton
  • 5,955
  • 7
  • 48
  • 50
1

var:

  • Declare a variable whose value can be changed at any time.
  • This is commonly used for declaring a variable with global scope.
  • It is re-assign able.
  • It is not re-declarable in its scope.

val:

  • It is used to define constants at run time. A major difference from const.
  • It is not re-assign able in its scope.
  • It is not re-declarable in its scope.
  • The declaration is block function scoped.
Anand Gaur
  • 225
  • 2
  • 10
0

val (from value): Immutable reference. A variable declared with val can’t be reassigned after it’s initialized. It corresponds to a final variable in Java.

var (from variable): Mutable reference. The value of such a variable can be changed. This declaration corresponds to a regular (non-final) Java variable.

Gulzar Bhat
  • 1,255
  • 11
  • 13
0

VAR is used for creating those variable whose value will change over the course of time in your application. It is same as VAR of swift, whereas VAL is used for creating those variable whose value will not change over the course of time in your application.It is same as LET of swift.

Ashutosh Shukla
  • 358
  • 5
  • 14
0

val - Immutable(once initialized can't be reassigned)

var - Mutable(can able to change value)

Example

in Kotlin - val n = 20 & var n = 20

In Java - final int n = 20; & int n = 20;

Najib.Nj
  • 3,706
  • 1
  • 25
  • 39
0

In Kotlin we use var to declare a variable. It is mutable. We can change, reassign variables. Example,

fun main(args : Array<String>){
    var x = 10
    println(x)

    x = 100 // vars can reassign.
    println(x)
}

We use val to declare constants. They are immutable. Unable to change, reassign vals. val is something similar to final variables in java. Example,

fun main(args : Array<String>){
    val y = 10
    println(y)

    y = 100 // vals can't reassign (COMPILE ERROR!).
    println(y)
}
0

I get the exact answer from de-compiling Kotlin to Java.

If you do this in Kotlin:

data class UsingVarAndNoInit(var name: String)
data class UsingValAndNoInit(val name: String)

You will get UsingVarAndNoInit:

package classesiiiandiiiobjects.dataiiiclasses.p04variiiandiiival;

import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

public final class UsingVarAndNoInit {
  @NotNull private String name;

  @NotNull
  public final String getName() {
    return this.name;
  }

  public final void setName(@NotNull String string) {
    Intrinsics.checkParameterIsNotNull((Object) string, (String) "<set-?>");
    this.name = string;
  }

  public UsingVarAndNoInit(@NotNull String name) {
    Intrinsics.checkParameterIsNotNull((Object) name, (String) "name");
    this.name = name;
  }

  @NotNull
  public final String component1() {
    return this.name;
  }

  @NotNull
  public final UsingVarAndNoInit copy(@NotNull String name) {
    Intrinsics.checkParameterIsNotNull((Object) name, (String) "name");
    return new UsingVarAndNoInit(name);
  }

  @NotNull
  public static /* bridge */ /* synthetic */ UsingVarAndNoInit copy$default(
      UsingVarAndNoInit usingVarAndNoInit, String string, int n, Object object) {
    if ((n & 1) != 0) {
      string = usingVarAndNoInit.name;
    }
    return usingVarAndNoInit.copy(string);
  }

  public String toString() {
    return "UsingVarAndNoInit(name=" + this.name + ")";
  }

  public int hashCode() {
    String string = this.name;
    return string != null ? string.hashCode() : 0;
  }

  public boolean equals(Object object) {
    block3:
    {
      block2:
      {
        if (this == object) break block2;
        if (!(object instanceof UsingVarAndNoInit)) break block3;
        UsingVarAndNoInit usingVarAndNoInit = (UsingVarAndNoInit) object;
        if (!Intrinsics.areEqual((Object) this.name, (Object) usingVarAndNoInit.name)) break block3;
      }
      return true;
    }
    return false;
  }
}

You will also get UsingValAndNoInit:

package classesiiiandiiiobjects.dataiiiclasses.p04variiiandiiival;

import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

public final class UsingValAndNoInit {
  @NotNull private final String name;

  @NotNull
  public final String getName() {
    return this.name;
  }

  public UsingValAndNoInit(@NotNull String name) {
    Intrinsics.checkParameterIsNotNull((Object) name, (String) "name");
    this.name = name;
  }

  @NotNull
  public final String component1() {
    return this.name;
  }

  @NotNull
  public final UsingValAndNoInit copy(@NotNull String name) {
    Intrinsics.checkParameterIsNotNull((Object) name, (String) "name");
    return new UsingValAndNoInit(name);
  }

  @NotNull
  public static /* bridge */ /* synthetic */ UsingValAndNoInit copy$default(
      UsingValAndNoInit usingValAndNoInit, String string, int n, Object object) {
    if ((n & 1) != 0) {
      string = usingValAndNoInit.name;
    }
    return usingValAndNoInit.copy(string);
  }

  public String toString() {
    return "UsingValAndNoInit(name=" + this.name + ")";
  }

  public int hashCode() {
    String string = this.name;
    return string != null ? string.hashCode() : 0;
  }

  public boolean equals(Object object) {
    block3:
    {
      block2:
      {
        if (this == object) break block2;
        if (!(object instanceof UsingValAndNoInit)) break block3;
        UsingValAndNoInit usingValAndNoInit = (UsingValAndNoInit) object;
        if (!Intrinsics.areEqual((Object) this.name, (Object) usingValAndNoInit.name)) break block3;
      }
      return true;
    }
    return false;
  }
}

There are more examples here: https://github.com/tomasbjerre/yet-another-kotlin-vs-java-comparison

Tomas Bjerre
  • 3,270
  • 22
  • 27
0

Normal

  • Val is using for static field like in Java as Static Keyword

  • Like Static in Java/ Same as in kotlin

  • And Var denotes Variable Field in Kotlin that, you can change it.

  • Mostly Static is used when you want to save value in static memory at once,

Example:

 if you assign

 val a=1
 a=3  You can not change it 
  • You can not change, this is final value and Static

    var b=2

    b=4 U can change it

Zoe
  • 27,060
  • 21
  • 118
  • 148
Zafar Hussain
  • 264
  • 2
  • 10
  • This is completely wrong. Ignoring the capitalization issues, this completely misunderstands the `static` keyword in Java. – Ryan M Mar 28 '23 at 06:02
0

I'm late to the party, but there's one difference that I haven't seen mentioned. You can use val to assign a local variable in a when expression, but trying to use var will produce a compiler error:

sealed class Token {
    data class StringToken(val value: String) : Token()
    data class BoolToken(val value: Boolean) : Token()
}

fun getToken() : Token = Token.BoolToken(true)

val output = when (val token = getToken()) {
    is Token.StringToken -> token.value
    is Token.BoolToken -> token.value.toString()
}

This allows you to get access to the correctly type-inferred value in the expressions on the right.

NickL
  • 1,870
  • 2
  • 15
  • 35
0

We use var to declare variables and we use val to create constants which in java are preceded by the reserved word final

Elizeu Santos
  • 21
  • 1
  • 4
-2
fun copyAddress(address: Address): Address {
    val result = Address() // there's no 'new' keyword in Kotlin
    result.name = address.name // accessors are called
    **result = Address() // This is not possible because its **val****
    return result
}

fun copyAddress(address: Address): Address {
    var result = Address() // there's no 'new' keyword in Kotlin
    result.name = address.name // accessors are called
    **result = Address() // This is possible because its **var****
    return result
}

You can re-initialize an object when its var, but not when its val. Using property is different, property has its own access specifiers and getter methods defined. Which determines the behavior's. Please let me know if its not clarified!!

Varun Chandran
  • 647
  • 9
  • 23
-13

var is a variable like any other language. eg.

var price: Double

On the other side, val provides you feature of referencing. eg.

val CONTINENTS = 7
// You refer this to get constant value 7. In this case, val acts as access
// specifier final in Java

and,

val Int.absolute: Int
    get() {
        return Math.abs(this)
    }
// You refer to the newly create 'method' which provides absolute value 
// of your integer

println(-5.absolute) // O.P: 5
Mukund Desai
  • 100
  • 2