Kotlin is a statically typed programming language for modern multi-platform applications. One of its distinguishing features is the way it handles variables with the use of val and var. Both are used to declare variables, but they have important differences. In this article, we'll discuss what sets them apart and how to choose the right one for your needs.
Immutable Variables: val
Variables declared using val are immutable. Once they are initialized, their values cannot be changed. This is equivalent to a final variable in Java. It's ideal for values that should remain constant throughout the lifecycle of the program.
val numberOfDaysInWeek = 7
// numberOfDaysInWeek = 8 // This will result in a compile-time error
In the example above, numberOfDaysInWeek is declared with val, so attempting to change it later will cause a compilation error.
Mutable Variables: var
Variables declared with var are mutable, meaning their values can be modified after initialization. Use var when you know the value of the variable will change. This is more flexible, akin to regular variable usage in many other languages, such as Java and Python.
var counter = 0
counter = 10 // This is allowed and updates the counter variable
For example, the counter variable can freely change its value from 0 to 10 without any issues.
When to Use val and var
Deciding between val and var might seem trivial, but it can significantly impact the readability and maintainability of your code:
- Use
valwhen you handle values that shouldn’t change unexpectedly, such as configurations, constants, or interim results explicitly calculated once and meant for repeated use. - Use
varwhen the value is likely to change, such as counters, accumulators, or stateful objects.
Example Use Cases
Consider a user profile object where certain properties like user id and username might not change once assigned, whereas login attempts might be an updatable count:
data class UserProfile(
val userId: String,
val username: String,
var loginAttempts: Int
)
fun main() {
val profile = UserProfile("123", "johndoe", 0)
// Modifying loginAttempts is allowed
profile.loginAttempts += 1
println(profile.loginAttempts) // Output: 1
// Attempting to change userId or username will result in a compilation error
// profile.userId = "456" // Error: Val cannot be reassigned
}
By using val for userId and username, you reinforce their immutability and intention of stable identity traits, while var allows loginAttempts to be flexible.