Salah satu kekuatan utama Kotlin adalah interoperabilitas penuh dengan Java: kode Kotlin dapat memakai library Java tanpa wrapper, tanpa JNI, tanpa boilerplate. Kita dapat membuat instance java.util.ArrayList langsung, memanggil Math.max(...), dan mengakses LocalDate.getDayOfMonth() seolah-olah semua itu kode Kotlin asli. Bab ini membahas tiga aspek inti pemanggilan Java dari Kotlin: konstruksi tanpa new, pemakaian static method, dan transformasi otomatis getter/setter menjadi properti.
Tiga Aturan Utama Interoperabilitas #
Saat memakai kode Java dari Kotlin, tiga aturan berikut berlaku konsisten:
| Aturan | Java | Kotlin |
|---|---|---|
| Konstruksi objek | new ArrayList<Integer>() | ArrayList<Int>() (tanpa new) |
| Method statis | Math.max(a, b) | Math.max(a, b) (sama persis) |
| Getter/setter | date.getDayOfMonth() | date.dayOfMonth (properti sintaks) |
Tidak ada wrapper, tidak ada adaptasi manual. Yang berubah hanya sintaks pemanggilan: kata kunci new dihapus, dan getter getXxx() menjadi properti .xxx.
Contoh Lengkap: Memakai Koleksi, Static, dan File Java #
Kode berikut memakai beberapa kelas Java sekaligus — ArrayList, HashMap, Properties, LocalDate, File, Math, System, dan Collections:
import java.util.ArrayList
import java.util.HashMap
import java.time.LocalDate
import java.io.File
// Demonstrasi pemanggilan kode Java dari Kotlin:
// - Konstruktor Java langsung dipakai tanpa 'new'
// - Static method dipanggil seperti biasa
// - Getter/setter Java otomatis menjadi properti Kotlin
class Konfigurasi {
// Memakai kelas Java java.util.Properties sebagai field
private val prop: java.util.Properties = java.util.Properties()
fun simpan(kunci: String, nilai: String) {
prop.setProperty(kunci, nilai) // method Java setProperty
}
fun ambil(kunci: String): String? = prop.getProperty(kunci) // getProperty mengembalikan String?
}
fun main() {
// 1. Memakai kelas Java koleksi: java.util.ArrayList
val daftar: ArrayList<Int> = ArrayList<Int>()
daftar.add(10)
daftar.add(20)
daftar.add(30)
println("=== java.util.ArrayList ===")
println("daftar : $daftar")
println("ukuran : ${daftar.size}") // getter -> properti
println("elemen ke-1 : ${daftar[1]}") // index access -> get(1)
// 2. java.util.HashMap dengan operator Kotlin
val peta: HashMap<String, String> = HashMap()
peta["nama"] = "Budi" // setProperty via Kotlin
peta["email"] = "[email protected]"
println()
println("=== java.util.HashMap ===")
println("peta : $peta")
println("nama : ${peta["nama"]}") // peta.get("nama")
println("tidakAda : ${peta["tidakAda"]}") // null (platform type)
// 3. Static method Java: Math, System, Collections
println()
println("=== Static method Java ===")
println("Math.max(3,7) : ${Math.max(3, 7)}")
println("Math.abs(-5) : ${Math.abs(-5)}")
println("System.lineSeparator().length: ${System.lineSeparator().length}")
val tidakDiubah = java.util.Collections.unmodifiableList(daftar)
println("unmodifiable : $tidakDiubah")
// 4. Getter/setter Java otomatis menjadi properti Kotlin
val tanggal = LocalDate.of(2026, 1, 15)
println()
println("=== Getter sebagai properti ===")
println("tanggal : $tanggal")
println("tahun : ${tanggal.year}") // getYear() -> year
println("bulan : ${tanggal.monthValue}") // getMonthValue() -> monthValue
println("hari : ${tanggal.dayOfMonth}") // getDayOfMonth() -> dayOfMonth
// 5. Memakai kelas Java I/O: File
val berkas: File = File("/tmp/belajar_kotlin_calling_java.txt")
berkas.writeText("Halo dari Kotlin\nBaris kedua\n")
println()
println("=== java.io.File ===")
println("path : ${berkas.absolutePath}")
println("ukuran (byte) : ${berkas.length()}") // length() -> length
println("ada? : ${berkas.exists()}") // exists() -> exists
println("isi :")
berkas.readLines().forEach { println(" | $it") }
berkas.delete() // hapus file setelah dipakai
// 6. Memakai Konfigurasi lokal yang membungkus java.util.Properties
val cfg = Konfigurasi()
cfg.simpan("versi", "1.0.0")
cfg.simpan("mode", "produksi")
println()
println("=== Wrapper java.util.Properties ===")
println("versi : ${cfg.ambil("versi")}")
println("tidakAda : ${cfg.ambil("tidakAda")}")
}Output yang Dihasilkan:
=== java.util.ArrayList ===
daftar : [10, 20, 30]
ukuran : 3
elemen ke-1 : 20
=== java.util.HashMap ===
peta : {nama=Budi, [email protected]}
nama : Budi
tidakAda : null
=== Static method Java ===
Math.max(3,7) : 7
Math.abs(-5) : 5
System.lineSeparator().length: 1
unmodifiable : [10, 20, 30]
=== Getter sebagai properti ===
tanggal : 2026-01-15
tahun : 2026
bulan : 1
hari : 15
=== java.io.File ===
path : /tmp/belajar_kotlin_calling_java.txt
ukuran (byte) : 29
ada? : true
isi :
| Halo dari Kotlin
| Baris kedua
=== Wrapper java.util.Properties ===
versi : 1.0.0
tidakAda : nullMari kita telaah baris-baris kode di atas:
- Baris 14 (
ArrayList<Int>()): konstruktor Java dipanggil tanpanew. Tipe generik JavaIntegersecara otomatis dipetakan keIntKotlin (autoboxing transparan).daftar.add(10)memanggilArrayList.add(Integer)secara langsung. - Baris 25 (
peta["nama"] = "Budi"): operator Kotlin[]padajava.util.HashMapditerjemahkan keput("nama","Budi"). Membacapeta["nama"]diterjemahkan keget("nama"). Hasilget()dari Java adalah tipe platform — Kotlin memperlakukannya sebagaiString?(nullable) untuk keamanan. - Baris 33-36 (
Math.max,System.lineSeparator()): method statis Java dipanggil persis seperti di Java. Kotlin tidak mengganti sintaks pemanggilan statik.System.lineSeparator()mengembalikanString— perhatikan bahwa di Linux ini hanya satu karakter\n, sehingga.lengthbernilai 1. - Baris 43 (
tanggal.year,tanggal.monthValue): getter JavagetYear()dangetMonthValue()otomatis menjadi properti KotlinyeardanmonthValue. Kompilator mendeteksi pasangangetXxx/setXxxdan menyajikan ulang sebagai properti. Pemanggilantanggal.getDayOfMonth()pun juga valid, namun sintaks properti lebih idiomatik. - Baris 50-57 (
berkas.writeText(...),berkas.readLines()):java.io.Filetidak punya methodwriteTextdi sisi Java. Method ini adalah extension function yang ditambahkan Kotlin keFilemelalui standard library. Kotlin menambah banyak helper seperti ini tanpa mengubah kelas Java asli. - Baris 62-66 (
Konfigurasilokal): kelas Kotlin sendiri memakaijava.util.Propertiessebagai field privat. Tipe kembalianprop.getProperty(kunci)dideklarasikan eksplisit sebagaiString?agar pemanggil Kotlin tahu bahwa nilai bisanullbila kunci tidak ditemukan.
Operator Kotlin di Atas Koleksi Java #
Kotlin menambah beberapa operator pada koleksi Java yang membuat pemakaian lebih ringkas:
| Operator Kotlin | Pemanggilan Java Ekuivalen |
|---|---|
daftar[i] | daftar.get(i) |
daftar[i] = x | daftar.set(i, x) / daftar.add(i, x) |
peta[k] | peta.get(k) |
peta[k] = v | peta.put(k, v) |
daftar += x | daftar.add(x) (untuk MutableList) |
daftar -= x | daftar.remove(x) (untuk MutableList) |
Operator [] dan += membuat kode terlihat idiomatik Kotlin walau di balik layar memakai method Java. Pemakaian ini tidak menambah overhead — kompilator menerjemahkan langsung ke method Java asli.
Referensi Lanjutan #
- Calling Java from Kotlin — dokumentasi resmi Kotlin untuk memanggil kode Java dari Kotlin
Selanjutnya #
Arah sebaliknya — memanggil kode Kotlin dari Java — juga penuh sehingga kedua bahasa dapat saling memakai library. Bab Calling Kotlin from Java akan membahas bagaimana top-level function Kotlin dilihat sebagai method statis di Java, serta peran anotasi @JvmStatic dan @JvmOverloads.