← all topics05 / 05 · learn android

05 · learn android

From Java to Kotlin

Unlearning boilerplate, not memorising syntax

Every pairing is the same lesson: a Java pattern you typed by habit became a language feature.

Moving from Java to Kotlin is frequently framed as "learn the new syntax," which gets it backwards. The syntax is the easy part. The actual migration is unlearning the habits Java forced on you — the getters and setters, the null checks everywhere, the anonymous inner classes — and trusting a language that lets you write the intent in one line instead of thirty.

The language is opinionated on purpose: it wants you to write less, and to write code where the bugs you'd normally write can't be written.

The mental model

How it fits together

JavaKotlin

POJO → data class

~30 lines + getters/setters
data class Dev(var name: String)

null handling

if (x != null) { … }
x?.length · x ?: ""

switch → when

switch + break
when (score) { 9, 10 -> … }

static utils → extensions

Utils.triple(3)
3.triple()

type check + cast

(Car) obj
if (obj is Car) { … } // smart cast

Key concepts

The ideas to internalise

Null-safety

Types are non-null by default; opt in with ?. The compiler forces you to handle nullability before you use the value — whole classes of NPE become impossible to write.

val vs var

Read-only vs mutable. Read-only is the default you should reach for; it's like final but the norm.

data class

A full POJO — getters, setters, equals, hashCode, toString — collapses to one line. The single biggest productivity win in the language.

when

switch becomes an expression that returns a value and needs no break. It reads like the decision, not the control flow.

Extension functions

fun Int.triple() means 3.triple() instead of Utils.triple(3). Add methods to types you don't own, without inheritance.

Smart casts

if (obj is Car) { … } — the compiler already knows obj is a Car inside the block. No explicit cast.

Side by side

Java → Kotlin, one pairing at a time

Print

java

System.out.println("Hi");

kotlin

println("Hi")

Variables

java

final String name = "John";

kotlin

val name = "John"

Null-safe access

java

if (text != null) { text.length(); }

kotlin

text?.length

or text ?: "" for a default

POJO

java

~30 lines of getters/setters/equals

kotlin

data class Dev(var name: String)

Switch

java

switch (x) { case 1: …; break; }

kotlin

when (x) { 1 -> … }

For loop

java

for (int i = 1; i <= 10; i++)

kotlin

for (i in 1..10)

Static util

java

Utils.triple(3)

kotlin

3.triple()

extension function

Type check + cast

java

if (obj instanceof Car) { (Car) obj; }

kotlin

if (obj is Car) { … }

smart cast

The takeaway

New Kotlin developers translate Java line-by-line and produce Kotlin that looks like Java with shorter keywords. The moment they get it is when they start reaching for the construct that expresses the intent — and the boilerplate disappears on its own.