Episode ini membedah arsitektur Kotlin: struktur program yang tersusun dari file, package, fungsi, dan class; proses kompilasi menjadi bytecode JVM; sistem tipe dengan null-safety; serta gambaran umum coroutines dan model concurrency modern.

Setelah environment siap di episode 0 dan motivasi jelas di episode 1, sekarang waktunya memahami bagaimana Kotlin bekerja dari dalam. Episode 2 membedah arsitektur bahasa: bagaimana program disusun, bagaimana kode diterjemahkan menjadi bytecode JVM, bagaimana sistem tipe menegakkan keamanan, dan bagaimana concurrency ditangani.
Pemahaman arsitektur ini bukan sekadar teori. Ketika kalian menghadapi error aneh di production, memahami alur kompilasi dan model tipe akan membantu kalian menebak akar masalah jauh lebih cepat. Ini juga membangun mental model yang diperlukan untuk episode 3 sampai 9.
Di akhir episode ini kalian akan bisa menjelaskan jalur hidup sebuah program Kotlin: dari source file, melewati compiler, menjadi bytecode, sampai dieksekusi JVM.
Sebuah program Kotlin disusun dari file .kt yang dikelompokkan dalam package. Berbeda dengan Java, Kotlin mengizinkan deklarasi top-level seperti fungsi dan properti langsung di level file, tanpa harus dibungkus class:
package id.devnull.contoh
fun sapa(nama: String): String = "Halo, $nama"
val versi = "1.0"Fungsi sapa dan properti versi di atas hidup di level file, dan bisa dipanggil langsung dari file lain di package yang sama. Direktori file tidak harus cocok dengan package — Kotlin tidak seketat Java dalam hal ini, meskipun konvensi menyarankan keduanya selaras.
Titik masuk eksekusi adalah fungsi main. Dengan Kotlin 2.x, kalian bisa menulisnya tanpa parameter, atau dengan parameter array String:
fun main(args: Array<String>) {
println("Jumlah argumen: ${args.size}")
}Jika kalian menjalankan program ini lewat kotlinc Main.kt -include-runtime -d main.jar lalu java -jar main.jar, fungsi main akan dieksekusi oleh JVM. String templates dengan ${args.size} adalah contoh ekspresi yang akan dibahas di episode 3.
Kotlin tidak ditafsirkan seperti bahasa scripting — dia dikompilasi. Compiler K2 menerjemahkan source .kt menjadi .class yang berisi bytecode JVM. Alur singkatnya: source file diproses K2, dihasilkan bytecode, lalu dijalankan oleh JVM bersama library runtime Kotlin.
Untuk melihat bytecode hasil kompilasi, kalian bisa memakai tool bawaan JDK:
kotlinc Main.kt
javap -c MainKt.classPerintah javap -c MainKt.class menampilkan instruksi bytecode dari class hasil kompilasi. Nama class menjadi MainKt dengan akhiran Kt karena deklarasi top-level — detail kecil yang sering mengejutkan pengembang yang baru pindah dari Java.
Karena format outputnya sama (bytecode JVM), Kotlin dan Java bisa saling memanggil secara langsung. Library Java seperti SLF4J, Jackson, atau Spring bisa dipakai tanpa adapter, dan sebaliknya class Kotlin terlihat seperti class Java biasa bagi panggilan dari sisi Java. Episode 17 akan membahas jembatan interop ini secara mendalam.
Kotlin adalah bahasa dengan tipe statis: tipe setiap ekspresi sudah diketahui saat kompilasi. Namun Kotlin menerapkan type inference, sehingga kalian jarang menulis tipe secara eksplisit:
val jumlah = 10
val pesan = "teks"
val harga = 19.99Variabel jumlah diinferensikan sebagai Int, pesan sebagai String, dan harga sebagai Double. Compiler tetap memeriksa semua operasi terhadap tipe yang diketahui, jadi keamanan tipe tidak berkurang meskipun sintaksnya ringkas.
Fitur arsitektur paling penting: Kotlin memisahkan tipe nullable dan non-nullable di level tipe. Variabel String tidak pernah bisa bernilai null; untuk itu kalian perlu String?. Compiler memaksa kalian menangani kemungkinan null, sehingga sebagian besar NullPointerException terdeteksi saat kompilasi. Detail lengkapnya akan dibahas di episode 6.
Kotlin memperkenalkan coroutines sebagai model utama untuk concurrency dan asynchrony. Berbeda dengan thread yang mahal untuk dibuat, coroutine adalah lightweight thread yang bisa menjalankan jutaan instance pada satu thread fisik. Operasi seperti panggilan jaringan tidak memblokir thread, melainkan menangguhkan eksekusi dan melanjutkannya nanti.
Konsep inti yang harus dipahami sekarang: suspend function adalah fungsi yang bisa menangguhkan eksekusinya tanpa memblokir thread. Coroutine scope, dispatcher, dan struktur kontrolnya akan dibahas menyeluruh di episode 9. Untuk saat ini, cukup ingat bahwa coroutines adalah fondasi async di Kotlin — di Android maupun backend.
Peta konsep episode ini:
Episode 2 memberi kalian cetak biru bagaimana Kotlin bekerja: bagaimana program disusun dalam file dan package, bagaimana kompilasi menghasilkan bytecode yang interoperabel dengan Java, bagaimana sistem tipe menegakkan keamanan, dan bagaimana coroutines menangani concurrency tanpa rasa sakit.
Inti yang harus dibawa pulang:
Di episode 3 selanjutnya kita akan membahas Kotlin syntax dan basic constructs — variabel val dan var, tipe data, string templates, control flow dengan if dan when, fungsi dengan default arguments, hingga extension functions dan infix notation. Ini adalah bekal sintaks yang akan dipakai di setiap episode berikutnya.