Getting Started
🚀 Getting Started with Kotlin
☕ What Is Kotlin, and Why Learn It?
Kotlin is:
- Statically typed — every value has a type, checked at compile time (like TypeScript, unlike plain JavaScript)
- JVM-based — Kotlin source compiles to the same bytecode Java does, and runs on the same virtual machine
- 100% Java-interoperable — Kotlin code can call Java libraries directly, and vice versa
- Android's preferred language — Google made Kotlin the recommended language for Android development in 2019, ahead of Java
- Designed to fix Java's pain points — null safety, less boilerplate, and expression-oriented syntax are all direct responses to common Java frustrations
Kotlin vs Java vs JavaScript, at a Glance
| Trait | JavaScript | Java | Kotlin |
|---|---|---|---|
| Typing | Dynamic | Static, verbose | Static, inferred |
| Where it runs | Browser / Node | JVM | JVM (also JS, Native) |
| Null handling | undefined / null, unchecked | null, unchecked (NPEs) | Null safety built into the type system |
| Semicolons | Optional (ASI) | Required | Optional |
| Entry point | Top-level script code | public static void main(String[] args) | fun main() |
▶️ Your First Kotlin Program
Hello, Kotlin
// hello.kt fun main() { println("Hello, Kotlin!") }
Run it (from the command line, with the Kotlin compiler installed):
$ kotlinc hello.kt -include-runtime -d hello.jar $ java -jar hello.jar Hello, Kotlin!
In practice, almost nobody runs Kotlin this way day to day — IntelliJ IDEA (or Android Studio, which is built on it) compiles and runs Kotlin with a single click. The command-line path above is worth seeing once so fun main() doesn't feel like magic: it compiles to a .jar, which runs on the JVM exactly like compiled Java would.
Notice there's no class wrapping main, and no semicolon at the end of the println line — both required in Java, both optional in Kotlin. fun declares a function (short for function), and top-level functions — ones that live outside any class — are completely normal in Kotlin, unlike Java where every method must belong to a class.
📦 val vs var
Kotlin has exactly two ways to declare a value, and the choice is deliberate every time:
val name = "Philip" // read-only reference — cannot be reassigned var score = 0 // mutable — can be reassigned score = 10 // fine, score is a var name = "Someone else" // compile error — val cannot be reassigned
val — like JS const
A val is a read-only reference, assigned once. It maps directly onto JavaScript's const — same idea, same restriction. In Kotlin, val is the default choice; you reach for var only when you know a value needs to change.
var — like JS let
A var can be reassigned, the same as JavaScript's let. There's no Kotlin equivalent of JavaScript's old var keyword with its confusing function-scoping — Kotlin's var behaves like a normal block-scoped mutable variable.
Declaring a Mutable Value: Java vs Kotlin
| Language | Immutable | Mutable |
|---|---|---|
| Java | final int score = 0; | int score = 0; |
| JavaScript | const score = 0; | let score = 0; |
| Kotlin | val score = 0 | var score = 0 |
Java's default is mutable — you have to opt in to immutability with final, and most Java code doesn't bother. Kotlin flips that: val is the natural first choice, which pushes code toward fewer accidental mutations without any extra ceremony.
🔢 Basic Types & Type Inference
Kotlin's built-in types cover the same ground as Java's primitives, but without the primitive/object split:
val age: Int = 33 val price: Double = 19.99 val isReady: Boolean = true val initial: Char = 'P' val title: String = "Learning Blog" // The type annotations above are optional — Kotlin infers them: val inferredAge = 33 // inferred as Int val inferredPrice = 19.99 // inferred as Double
vs Java: No Primitives
Java has a hard split between primitives (int, double, boolean) and their boxed object wrappers (Integer, Double, Boolean). Kotlin has just one type per concept — Int, Double, Boolean — and the compiler quietly uses the efficient primitive form under the hood wherever it can.
vs JavaScript: No Number-for-Everything
JavaScript has a single number type for all numeric values. Kotlin distinguishes Int (whole numbers) from Double (decimals) at compile time — mixing them without an explicit conversion is a compile error, not a silent runtime surprise.
Type inference means you rarely write the type annotation explicitly — Kotlin figures out Int, String, etc. from the value on the right-hand side, the same way TypeScript's let x = 5 infers number. The annotation is still useful (and sometimes required) when the type isn't obvious from context, such as an empty collection or a function parameter.
📝 String Templates
Kotlin builds strings with string templates — the direct equivalent of JavaScript's template literals, but with a different symbol:
val name = "Philip" val age = 33 // Simple variable — just $name println("Hello, $name!") // Hello, Philip! // Expression — needs ${ } braces println("Next year you'll be ${age + 1}") // Next year you'll be 34
Template Syntax: JavaScript vs Kotlin
| JavaScript | Kotlin | |
|---|---|---|
| Delimiter | Backticks: `...` | Double quotes: "..." |
| Simple variable | ${name} | $name |
| Expression | ${age + 1} | ${age + 1} |
The key difference: Kotlin string templates live inside ordinary double-quoted strings, not a special delimiter — so every String in Kotlin is automatically template-capable. For a single variable, the braces are optional ($name works fine); for anything more than a bare variable — a property access, a function call, an expression — the ${ } braces are required.
Because $ triggers template interpolation, a literal dollar sign in a Kotlin string needs escaping: "Price: \$19.99". This is the same category of gotcha as needing to escape a literal backtick inside a JavaScript template literal.
💻 Coding Challenges
Challenge 1: val vs var in Practice
Write a Kotlin program with a val holding your name and a var holding a counter starting at 0. Increment the counter three times and print it after each increment. Then try (and comment out) reassigning the val — note the compiler error.
Goal: Build muscle memory for choosing val by default and reaching for var only when needed.
Challenge 2: Typed Values & Inference
Declare five vals — one each of type Int, Double, Boolean, Char, and String — first with explicit type annotations, then rewritten with type inference (no annotations). Print all five using one println per value.
Goal: Get comfortable with Kotlin's five basic types and when inference does the work for you.
Challenge 3: String Templates
Given a val for a product name and a var for its price (a Double), print a single sentence using a string template that includes the name (simple interpolation) and the price with 10% tax added (expression interpolation with ${ }).
Goal: Practice both forms of string template interpolation in one realistic sentence.
Kotlin also compiles to JavaScript (Kotlin/JS) and native binaries (Kotlin/Native), but this course sticks to the JVM track throughout — it's the version used for Android development, which is the reason Kotlin is on the syllabus in the first place. Everything here transfers directly once the Android courses begin.
🎯 What's Next
Next chapter: Functions & Lambdas — default parameters, named arguments, single-expression functions, and Kotlin's lambda syntax.