Package mengelompokkan kode secara logis, tetapi untuk distribusi dan visibility kita memerlukan unit yang lebih besar: modul. Pada chapter ini kita akan mendefinisikan apa itu modul Kotlin, bagaimana modul dipetakan ke output build seperti jar (JVM) dan klib (Native), serta mengapa konsep modul menjadi fondasi bagi modifier visibility internal. Pemahaman ini melengkapi gambaran tentang package dan menjadi prasyarat sebelum membahas internal secara mendalam pada chapter berikutnya.
Definisi Modul di Kotlin #
Modul Kotlin adalah sekumpulan file Kotlin yang dikompilasi bersamaan dan menghasilkan satu artefak build. Biasanya modul = satu Gradle module = satu file build.gradle(.kts). Berikut beberapa contoh konkret:
- Aplikasi JVM tunggal: satu modul, output
jar. - Library yang dipakai aplikasi lain: satu modul terpisah, output
jaryang diterbitkan ke repository Maven. - Proyek Kotlin Multiplatform (KMP): satu modul per target (
commonMain,jvmMain,jsMain), masing-masing menghasilkan artefak sendiri. - Target Kotlin/Native: satu modul menghasilkan
klib(Kotlin library) atau binary native.
Dengan demikian, modul adalah unit distribusi sekaligus unit batasan visibility. Modifier internal membatasi panggilan agar hanya terjadi di dalam modul yang sama.
Output Build per Target #
| Target kompilasi | Output modul | Catatan |
|---|---|---|
| JVM | .jar | Paket standar untuk distribusi library JVM. |
| JS | .js + .kjsm | Berjalan di Node.js atau browser. |
| Native (Linux/macOS/Windows) | .klib atau binary native | klib adalah library Kotlin/Native. |
| Android | .aar | Mirip .jar plus resource Android. |
| Multiplatform | beberapa artefak | Setiap target menghasilkan output sendiri. |
Contoh Kode: Boundary Modul #
Kode berikut memperlihatkan bagaimana internal membatasi panggilan. Function validasiEmail hanya dapat dipanggil dari kode dalam modul yang sama:
// File: kotlin_modules.kt
// Mendemonstrasikan konsep modul Kotlin melalui internal visibility.
// Setiap berkas yang dikompilasi bersama dalam satu artefak build (jar/klib)
// dianggap sebagai satu modul.
package com.example.modul
// internal function: hanya dapat dipanggil dari kode dalam modul yang sama.
internal fun validasiEmail(email: String): Boolean {
return email.contains("@") && email.contains(".") && email.length > 5
}
// public function: bagian dari API publik modul; dapat dipanggil dari luar.
fun prosesEmail(email: String): String {
// validasiEmail dapat dipanggil karena berada dalam modul yang sama.
return if (validasiEmail(email)) {
"Email $email valid, diproses."
} else {
"Email $email tidak valid."
}
}
// Public class dengan implementation detail yang internal.
class Pengguna(val nama: String, email: String) {
// Properti public yang membungkus logic internal.
val emailValid: Boolean = validasiEmail(email)
// Fungsi private helper — detail implementasi class.
private fun tandaTangan(): String = "disigned-by-$nama"
fun profil(): String = "Pengguna($nama, emailValid=$emailValid, ${tandaTangan()})"
}
fun main() {
val p1 = Pengguna("Budi", "[email protected]")
val p2 = Pengguna("Siti", "data-tidak-lengkap")
println(p1.profil())
println(p2.profil())
println(prosesEmail("[email protected]"))
println(prosesEmail("tidak-valid"))
}Output yang Dihasilkan:
Pengguna(Budi, emailValid=true, disigned-by-Budi)
Pengguna(Siti, emailValid=false, disigned-by-Siti)
Email [email protected] valid, diproses.
Email tidak-valid tidak valid.Mari kita amati baris-baris di atas:
- Baris 8 (
internal fun validasiEmail): function internal. Karena bersifatinternal, kode di luar modul tidak dapat memanggilnya. Pada level bytecode JVM, function ini sebenarnya menjadipublicdengan nama yang di-mangle, tetapi kompilator Kotlin menolak panggilan dari file luar modul. - Baris 14 (
fun prosesEmail(email: String): String): function public. Menjadi bagian API publik modul. Di dalamnya, kita memanggilvalidasiEmail— panggilan internal-ke-internal diperbolehkan. - Baris 24 (
val emailValid: Boolean = validasiEmail(email)): properti public yang mengandalkan function internal. Ini adalah pola umum: API publik membungkus detail implementasi internal. - Baris 27 (
private fun tandaTangan()): helper private. Hanya dipanggil dari methodprofil()pada baris 29. - Baris 32-40 (
fun main): titik masuk. Membuat dua instancePenggunadan memanggilprosesEmail.main()berada dalam modul yang sama dengan deklarasi sehingga semua panggilan sah.
Modul pada Proyek Gradle #
Pada proyek Gradle, modul direpresentasikan oleh satu subproject Gradle. File settings.gradle.kts mendaftarkan modul-modul:
rootProject.name = "aplikasi-kasir"
include("app")
include("common")
include("data-model")Setiap entry include(...) adalah satu modul. Konsumen library hanya dapat memanggil deklarasi public, sedangkan deklarasi internal tetap tersembunyi meskipun kode konsumen berada di package yang sama persis.
Referensi Lanjutan #
- Packages — konteks modul Kotlin dan hubungannya dengan package di panduan resmi
- Gradle — definisi modul Gradle untuk project Kotlin
- Maven — alternatif build modul Kotlin dengan Maven
Selanjutnya #
Modul pada Gradle sering kali dipecah lagi menjadi source set untuk memisahkan kode produksi dan kode uji. Chapter Source Sets akan membahas konsep tersebut.