Table of contents
val and var
When switching from Java to Kotlin, variable declaration is the first thing you encounter. Instead of int x = 1, you have to choose between val and var.
fun main() {
val name = "Kotlin" // Cannot be changed once assigned
var count = 0 // Can be changed later
count = 1 // OK
// name = "Java" // Compile error
}
val is assigned once and that’s it; var allows reassignment later.
Why this distinction? When you have a guarantee that a value won’t change, there’s less to track when reading the code. You don’t need to worry about synchronization in multithreaded contexts, and it pairs well with a functional programming style. IntelliJ even warns you when you use var: “Couldn’t this be a val?”
The rule of thumb in practice is simple: start with val, and only switch to var when mutation is truly needed.
Type Inference
Kotlin infers types automatically, even if you don’t write them explicitly.
val message = "Hello" // String
val number = 42 // Int
val pi = 3.14 // Double
You can also be explicit. When declaring without an initial value, the type must be specified.
val name: String
name = "Kotlin"
Considering that Java only got var starting in version 10, Kotlin was designed with type inference as a fundamental feature from the start.
Basic Types
In Kotlin, everything is an object. Unlike Java, there’s no separate int and Integer — it’s unified into a single Int. The compiler handles optimizations behind the scenes, so there’s no need to worry about performance.
val age: Int = 25
val height: Double = 175.5
val initial: Char = 'K'
val isActive: Boolean = true
val big: Long = 100_000_000L // Underscores for digit grouping
The ability to insert underscores like 100_000_000L is a small feature but surprisingly handy. It makes large numbers and monetary amounts easy to read at a glance.
Nullable Types
One of Kotlin’s most praised features is its Nullable system. If you’re a Java developer, you’ve likely suffered from NullPointerExceptions — Kotlin catches these at compile time.
By default, all types are non-nullable.
var name: String = "Kotlin"
// name = null // Compile error
If null is needed, you must explicitly allow it by appending ? to the type.
var name: String? = "Kotlin"
name = null // OK
// name.length // Compile error — it could be null
println(name?.length) // Safe call — returns null if null
println(name?.length ?: 0) // Elvis operator — returns 0 if null
?. is the safe call operator. If the value is null, it doesn’t invoke the method and simply returns null. ?: is the Elvis operator — when the left side is null, it uses the right-side value instead.
At first, adding ? everywhere may feel tedious, but once you get used to it, you’ll find it more convenient since you can write code without worrying about NPEs.
String Templates
In Java, embedding variables in strings required concatenation with + or String.format(). In Kotlin, $ is all you need.
val language = "Kotlin"
val version = 2.0
println("$language $version") // Kotlin 2.0
println("${language.length} characters") // 6 characters
println("${if (version > 1.5) "latest" else "old version"}") // latest
For simple variables, use $variableName; for expressions, wrap them with ${}. This is especially useful when building log messages or error messages.
The next part covers Kotlin’s conditionals and loops. We’ll look at how if works as an expression and how when replaces Java’s switch.




Loading comments...