Variables, Null Safety, and String Templates
val vs. var
val name = "Ada" // read-only, cannot be reassigned
var xp = 0 // mutable, can be reassigned
xp += 10
val is Kotlin's default mindset: prefer values that never change once assigned, reach for var only when you genuinely need to reassign. Both still support full type inference, or an explicit type when you want one: val price: Double = 9.99.
Null safety
Kotlin's type system separates types that can hold null from types that can't, at compile time, which eliminates most NullPointerExceptions before the code ever runs.
var username: String = "ada" // can never be null
var nickname: String? = null // the ? makes it explicitly nullable
username = null // compile error, not allowed!
To work with a nullable value, Kotlin gives you two key operators:
// Safe call: returns null instead of crashing if nickname is null
println(nickname?.length)
// Elvis operator: provide a fallback when the left side is null
val length = nickname?.length ?: 0
nickname?.length reads as "if nickname isn't null, get its length, otherwise the whole expression is null", and ?: 0 reads as "...or 0 if that was null."
String templates
val xp = 50
println("Hello, $name! You have $xp XP.")
println("Next level in ${100 - xp} XP.")
$name substitutes a variable directly, ${...} is needed for full expressions, both are far more readable than Java's +-based string concatenation.
| val | var | |
|---|---|---|
| Reassignable | No | Yes |
| Mindset | Default choice | Only when needed |
| Java equivalent | final local variable | regular variable |