Menggabungkan teks dengan operator + masih praktis untuk dua-tiga nilai, tetapi kepraktisan itu cepat habis ketika satu kalimat membutuhkan sepuluh nilai sekaligus dengan posisi yang presisi. Untuk kebutuhan tersebut Java menyediakan pendekatan template: kita menulis pola string dengan format specifier sebagai lubang kosong, lalu mengirim data untuk mengisi lubang-lubang tersebut. Method String.format adalah pintu masuk paling umum, dan mesin di baliknya — class java.util.Formatter — adalah mesin yang sama yang akan kita pakai lagi pada printf dan System.console().readLine. Chapter ini membahas anatomi specifier, konversi yang paling sering dipakai, serta cara memakai ulang argumen.
Anatomi Format Specifier #
Setiap lubang kosong dalam template ditulis dengan pola berikut:
%[argument_index$][flags][width][.precision]conversionBagian yang wajib hanya tanda persen dan conversion — huruf yang menyatakan jenis data. Sisanya bersifat opsional dan akan kita bahas bertahap: indeks argumen di chapter ini, lebar serta presisi pada chapter Formatted Output. Berikut conversion yang paling sering dipakai:
| Specifier | Menerima | Hasil |
|---|---|---|
%s | object apa pun | representasi teks via String.valueOf |
%d | bilangan bulat (int, long, …) | angka tanpa desimal |
%f | bilangan desimal (float, double) | enam angka di belakang koma secara bawaan |
%b | boolean atau object apa pun | true/false |
%n | tanpa argumen | pemisah baris platform |
Membangun String dengan String.format #
String.format adalah method static pada class String yang mengembalikan string baru — template maupun argumen aslinya tidak berubah. Mari kita uji lima specifier sekaligus:
public class FormatSapaan {
public static void main(String[] args) {
String nama = "Budi";
int umur = 17;
double berat = 62.5;
boolean lulus = true;
String info = String.format(
"Nama: %s | Umur: %d | Berat: %f | Berat (1 desimal): %.1f | Lulus: %b%n",
nama, umur, berat, berat, lulus);
System.out.print(info);
System.out.println("Panjang info: " + info.length() + " karakter");
}
}Output yang Dihasilkan:
Nama: Budi | Umur: 17 | Berat: 62.500000 | Berat (1 desimal): 62.5 | Lulus: true
Panjang info: 81 karakterMari kita telaah bagian-bagian pentingnya:
- Baris 8-10 (
String.format(template, args...)): argumen pertama adalah template; argumen kedua dan seterusnya adalah data yang mengisi specifier secara berurutan —%sdiisinama,%ddiisiumur, dan seterusnya. - Specifiers
%fdan%.1f: keduanya menerimaberat, tetapi%ftanpa presisi mencetak62.500000(enam digit bawaan), sedangkan%.1fmembatasi menjadi satu digit desimal —62.5. - Specifier
%b: menerima nilaibooleanapa adanya; untuk object bukanboolean, nilainulldicetak sebagaifalsedan object apa pun yang tidak null dicetak sebagaitrue. - Specifier
%n: tidak mengonsumsi argumen; pemisah baris disisipkan langsung ke hasil.
Menyusun Template Multi-Baris #
Kekuatan template makin terasa saat hasil yang kita bangun berupa dokumen kecil multi-baris. Program berikut menyusun struk belanja, memaksa dua digit desimal untuk nominal uang, lalu mencetak string hasil tersebut — pembangunan dan pencetakan sepenuhnya terpisah:
public class StrukBelanja {
public static void main(String[] args) {
String nama = "Siti";
int jumlah = 3;
double hargaSatuan = 12500.0;
double total = jumlah * hargaSatuan;
String struk = String.format(
"STRUK BELANJA%nPembeli : %s%nItem : %d buku tulis%n"
+ "Harga : %.2f per item%nTotal : %.2f%nTerima kasih, %1$s!",
nama, jumlah, hargaSatuan, total);
System.out.println(struk);
}
}Output yang Dihasilkan:
STRUK BELANJA
Pembeli : Siti
Item : 3 buku tulis
Harga : 12500.00 per item
Total : 37500.00
Terima kasih, Siti!Dua hal patut digarisbawahi dari program tersebut. Pertama, operator + pada baris 9-10 hanya merangkai template di kode sumber agar baris kode tidak terlalu panjang — hasil gabungannya tetap satu template utuh bagi Formatter. Kedua, %1$s di akhir template memakai argumen pertama untuk kedua kalinya tanpa kita mengirim nama dua kali; string hasil disimpan dalam variabel struk sehingga dapat juga dikirim ke berkas, jaringan, atau komponen lain — bukan sekadar dicetak.
Menggunakan Ulang Argumen dengan Indeks #
Indeks argumen ditulis di antara % dan conversion dengan format N$, di mana N adalah posisi argumen mulai dari 1. Ada juga bentuk relatif %< yang berarti “argumen yang sama dengan specifier sebelumnya”:
public class IndeksArgumen {
public static void main(String[] args) {
String nama = "Siti";
int skor = 90;
System.out.println(String.format(
"Halo %1$s, skor %2$d milik %1$s.", nama, skor));
System.out.println(String.format(
"Skor %2$d dicetak lebih dulu, nama %1$s belakangan.", nama, skor));
System.out.println(String.format(
"%s dan %<s mendapat nilai sama.", nama));
}
}Output yang Dihasilkan:
Halo Siti, skor 90 milik Siti.
Skor 90 dicetak lebih dulu, nama Siti belakangan.
Siti dan Siti mendapat nilai sama.Baris pertama memakai %1$s dua kali sehingga argumen nama cukup dikirim sekali. Baris kedua membalik urutan pencetakan — %2$d lebih dulu — tanpa mengubah urutan argumen; trik ini berguna saat menerjemahkan kalimat yang tata bahasanya berbeda antarbahasa. Baris ketiga memperlihatkan bentuk relatif: %<s mengulang argumen yang dipakai specifier %s sebelumnya, sehingga hasilnya “Siti dan Siti”.
Memformat atau Menggabungkan #
Kapan + dan kapan String.format? Untuk dua nilai dengan pola sederhana, penggabungan + justru lebih ringkas dan mudah dibaca. Template menjadi pilihan ketika jumlah nilai banyak, ketika nilai yang sama dipakai berulang, ketika butuh presisi desimal tetap, atau ketika template akan disimpan sebagai konstanta yang dipisah dari data. Satu batasan penting: jika jumlah argumen tidak cocok dengan jumlah specifier, Formatter melempar exception saat program berjalan — compiler tidak memeriksa kecocokan tersebut. Setelah string hasil siap, langkah berikutnya sering kali tinggal mencetaknya; chapter Formatted Output membahas System.out.printf, pintu cepat yang memformat sekaligus mencetak dengan specifier yang sama persis.
Referensi #
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
FormatSapaan.java
Unduh berkaspublic class FormatSapaan {
public static void main(String[] args) {
String nama = "Budi";
int umur = 17;
double berat = 62.5;
boolean lulus = true;
String info = String.format(
"Nama: %s | Umur: %d | Berat: %f | Berat (1 desimal): %.1f | Lulus: %b%n",
nama, umur, berat, berat, lulus);
System.out.print(info);
System.out.println("Panjang info: " + info.length() + " karakter");
}
}
IndeksArgumen.java
Unduh berkaspublic class IndeksArgumen {
public static void main(String[] args) {
String nama = "Siti";
int skor = 90;
System.out.println(String.format(
"Halo %1$s, skor %2$d milik %1$s.", nama, skor));
System.out.println(String.format(
"Skor %2$d dicetak lebih dulu, nama %1$s belakangan.", nama, skor));
System.out.println(String.format(
"%s dan %<s mendapat nilai sama.", nama));
}
}
StrukBelanja.java
Unduh berkaspublic class StrukBelanja {
public static void main(String[] args) {
String nama = "Siti";
int jumlah = 3;
double hargaSatuan = 12500.0;
double total = jumlah * hargaSatuan;
String struk = String.format(
"STRUK BELANJA%nPembeli : %s%nItem : %d buku tulis%n"
+ "Harga : %.2f per item%nTotal : %.2f%nTerima kasih, %1$s!",
nama, jumlah, hargaSatuan, total);
System.out.println(struk);
}
}