Kita kini menguasai seluruh bahan dasarnya: package untuk organisasi, access modifier untuk batas API, JAR untuk pengemasan, dan module untuk kontrak dependensi. Saatnya merangkainya menjadi satu karya utuh — sebuah library yang dibagikan ke orang lain dan dipakai tanpa mereka membaca kode sumber kita. Menulis library melatih disiplin yang berbeda dari menulis aplikasi: setiap keputusan desain menjadi kontrak publik, dan setiap keputusan yang buruk akan menempel pada pengguna. Pada Chapter penutup Section ini kita akan menyusun library utilitas teks dari nol sampai siap rilis — struktur package, API yang minim, JAR terdokumentasi, dan nomor versi yang berdisiplin.
Lima Langkah Menyusun Library #
Resep umum yang kita ikuti sepanjang chapter ini:
- Susun package yang rapi — domain terbalik, struktur direktori konsisten.
- Kecilkan API publik — mulai package-private, naikkan ke
publichanya yang memang perlu. - Kemas menjadi JAR — satu berkas berversi, lengkap dengan module descriptor bila relevan.
- Dokumentasikan —
javadocyang jujur untuk setiap anggota publik. - Rilis dengan versi semantik — nomor yang memberi tahu pengguna seberapa besar perubahannya.
Langkah-langkahnya berurutan karena masing-masing membangun di atas yang sebelumnya; API yang belum stabil sulit didokumentasikan, dan dokumentasi yang belum ada membuat versi sulit dijanjikan.
Package Rapi dan API Publik Minim #
Library kita bernama teksutil dan dimiliki domain fiktif contoh.com, sehingga nama packagenya com.contoh.teksutil. Prinsip API-nya: dua method publik saja — hitungKata dan singkat — sementara pemecah kata menjadi method internal package-private. Kita uji coba dulu versi selevel (default package) agar bisa dijalankan langsung:
public class TeksUtil {
public static int hitungKata(String teks) {
if (teks == null || teks.isBlank()) {
return 0;
}
return pecahKata(teks).length;
}
public static String singkat(String teks, int maks) {
if (teks.length() <= maks) {
return teks;
}
return teks.substring(0, maks - 1) + "\u2026";
}
static String[] pecahKata(String teks) {
return teks.strip().split("\\s+");
}
}public class DemoTeksUtil {
public static void main(String[] args) {
String kalimat = "belajar java itu menyenangkan";
String panjang = "Belajar package dan module";
System.out.println("jumlah kata : " + TeksUtil.hitungKata(kalimat));
System.out.println("jumlah kata kosong : " + TeksUtil.hitungKata(" "));
System.out.println("singkatan : " + TeksUtil.singkat(panjang, 12));
}
}Output yang Dihasilkan:
jumlah kata : 4
jumlah kata kosong : 0
singkatan : Belajar pac…Bedah desainnya:
- Method
hitungKatadansingkatbermodifierpublic: keduanya adalah seluruh janji kita ke pengguna. Perilaku kasus kosong (teksnull, spasi saja) ditangani eksplisit — pengguna tidak boleh menebak. - Method
pecahKatapackage-private: detail implementasi pemecahan kalimat. Bila kelak kita menggantisplitdengan parser yang lebih cerdas, tidak ada pengguna yang terganggu karena method ini memang tidak pernah terlihat dari luar package. - Kedua method
staticdan murni: tanpa state tersimpan, library aman dipakai lintas thread dan mudah diuji — karakteristik yang tepat untuk utilitas.
Sebelum mengemas, uji dulu API-nya dari sudut pandang pengguna — berkas DemoTeksUtil.java di atas berperan sebagai konsumen pertama kita sekaligus uji perilaku kasus batas: teks kosong dan teks yang lebih panjang dari batas singkatan. Kebiasaan menguji lewat kode konsumen terpisah, bukan lewat method internal, menjaga kita jujur bahwa yang diuji memang hanya API publik.
Bentuk ber-package-nya tinggal menambah package com.contoh.teksutil; di baris pertama dan memindahkan berkas ke src/com/contoh/teksutil/TeksUtil.java — persis resep Chapter Package Declaration. Satu pengecekan terakhir sebelum mengemas: pastikan tidak ada class public di luar rencana API, karena begitu JAR dirilis, anggota publiknya menjadi kontrak yang diharapkan pengguna.
Mengemas JAR Berversi #
Dengan struktur ber-package, pengemasan menjadi empat perintah yang kita jalankan sungguhan:
javac -d kelas src/com/contoh/teksutil/TeksUtil.java
jar --create --file teksutil-1.0.0.jar -C kelas .
jar --list --file teksutil-1.0.0.jar
javac -cp teksutil-1.0.0.jar PakaiTeksUtil.java
java -cp teksutil-1.0.0.jar:. PakaiTeksUtilOutput yang Dihasilkan:
META-INF/
META-INF/MANIFEST.MF
com/
com/contoh/
com/contoh/teksutil/
com/contoh/teksutil/TeksUtil.class
4
Belajar pac…Opsi -C kelas . membungkus isi direktori keluaran kompilasi dengan path package-nya tetap utuh di dalam JAR, dan nama berkasnya menempelkan versi 1.0.0. Dua perintah terakhir berperan sebagai pengguna sungguhan: program PakaiTeksUtil di-compile dan dijalankan hanya dengan JAR di classpath — membuktikan library berdiri sendiri tanpa kode sumbernya. Untuk menjangkau pengguna module path, tambahkan module-info.java (module com.contoh.teksutil { exports com.contoh.teksutil; }) sebelum kompilasi — JAR yang sama lalu berlaku sebagai module bernama.
Dokumentasi dengan javadoc #
Library tanpa dokumentasi memaksa pengguna membaca kode. Tool javadoc di JDK menghasilkan halaman API dari komentar berformat khusus:
/**
* Menghitung jumlah kata pada sebuah teks.
* Teks kosong (null atau hanya spasi) menghasilkan 0.
*
* @param teks teks yang akan dihitung, boleh null
* @return jumlah kata pada teks
*/
public static int hitungKata(String teks) { ... }javadoc -d doc -quiet src/com/contoh/teksutil/TeksUtil.javaPerintah itu menghasilkan direktori doc/ berisi index.html dan halaman per class — dokumentasi bergaya persis halaman docs.oracle.com yang kita buka sepanjang Course. Parameter -quiet meredam laporan kemajuan; komentar javadoc untuk setiap anggota public membuat peringatan “no comment” hilang dan menegakkan kebiasaan mendokumentasikan API sebelum merilisnya.
Versi Semantik untuk Rilis #
Nomor versi adalah komunikasi. Konvensi semantic versioning (MAJOR.MINOR.PATCH, misalnya 1.4.2) memberi makna pada setiap kenaikan:
| Kenaikan | Arti bagi pengguna | Contoh |
|---|---|---|
PATCH (1.0.0 → 1.0.1) | perbaikan cacat, perilaku API tak berubah | koreksi hitungKata pada tab ganda |
MINOR (1.0.1 → 1.1.0) | fitur baru yang kompatibel mundur | method hitungKalimat baru |
MAJOR (1.1.0 → 2.0.0) | perubahan yang merusak kompatibilitas | hitungKata mengembalikan long |
Disiplinnya: rilis MINOR tidak boleh membuat kode pengguna yang ada gagal kompilasi, dan rilis MAJOR memberi sinyal agar pengguna memeriksa ulang pemakaiannya. Nomor ini ditulis pada nama JAR, di manifest, dan — bila library dipublikasikan — pada koordinat build tool seperti Maven (groupId:artifactId:version, contoh com.contoh:teksutil:1.0.0).
Referensi #
- Maven: panduan publikasi dan dependency management
- Oracle: jar — Tool Panduan JDK 25
- dev.java: Belajar Java
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
DemoTeksUtil.java
Unduh berkaspublic class DemoTeksUtil {
public static void main(String[] args) {
String kalimat = "belajar java itu menyenangkan";
String panjang = "Belajar package dan module";
System.out.println("jumlah kata : " + TeksUtil.hitungKata(kalimat));
System.out.println("jumlah kata kosong : " + TeksUtil.hitungKata(" "));
System.out.println("singkatan : " + TeksUtil.singkat(panjang, 12));
}
}
TeksUtil.java
Unduh berkaspublic class TeksUtil {
public static int hitungKata(String teks) {
if (teks == null || teks.isBlank()) {
return 0;
}
return pecahKata(teks).length;
}
public static String singkat(String teks, int maks) {
if (teks.length() <= maks) {
return teks;
}
return teks.substring(0, maks - 1) + "\u2026";
}
static String[] pecahKata(String teks) {
return teks.strip().split("\\s+");
}
}