Mengevaluasi sebuah kondisi berarti menjalankan seluruh pekerjaan yang dibutuhkan untuk menghitung nilainya — termasuk memanggil method pada setiap operand. Operator && dan || menyimpan rahasia yang menghemat pekerjaan itu: begitu kesimpulan sudah pasti dari operand kiri, operand kanan tidak pernah dievaluasi sama sekali. Perilaku ini bernama short-circuit evaluation — evaluasi hubung singkat — dan bukan optimasi opsional yang boleh datang pergi, melainkan jaminan tetap dari spesifikasi bahasa Java. Pada Chapter penutup Section ini kita buktikan perilakunya dengan method yang mencatat setiap pemanggilan, lalu menerapkannya pada pola pemeriksaan null yang dipakai hampir di setiap program Java nyata.
Cara Kerja Short-Circuit #
Aturannya ringkas. Pada a && b: bila a bernilai false, hasil pasti false apa pun nilai b, sehingga b dilewati. Pada a || b: bila a bernilai true, hasil pasti true sehingga b juga dilewati. Untuk membuktikannya, kita perlu operand yang meninggalkan jejak — method catatPembayaran berikut mencetak baris setiap kali dipanggil, sehingga output memperlihatkan dengan pasti method mana yang dieksekusi dan mana yang sama sekali tidak.
public class EfekSamping {
static boolean catatPembayaran(int jumlah) {
System.out.println(" -> method catatPembayaran dipanggil: " + jumlah);
return jumlah > 0;
}
public static void main(String[] args) {
System.out.println("Uji && : operand kiri menghasilkan false");
boolean hasil1 = catatPembayaran(0) && catatPembayaran(50000);
System.out.println("hasil1 = " + hasil1);
System.out.println("Uji || : operand kiri menghasilkan true");
boolean hasil2 = catatPembayaran(50000) || catatPembayaran(0);
System.out.println("hasil2 = " + hasil2);
}
}Output yang Dihasilkan:
Uji && : operand kiri menghasilkan false
-> method catatPembayaran dipanggil: 0
hasil1 = false
Uji || : operand kiri menghasilkan true
-> method catatPembayaran dipanggil: 50000
hasil2 = trueMari kita telaah bukti pada output tersebut:
- Baris 2-5 (
static boolean catatPembayaran(...)): method pencatat jejak — setiap pemanggilan mencetak satu baris berisi argumennya, lalu mengembalikantruebila jumlahnya positif. - Uji
&&(blok pertama): hanya satu baris jejak muncul.catatPembayaran(0)mengembalikanfalse, sehinggacatatPembayaran(50000)di operand kanan tidak pernah dipanggil — hasilnya pun langsungfalse. - Uji
||(blok kedua): kembali hanya satu baris jejak.catatPembayaran(50000)mengembalikantrue, operand kanan dilewati, dan hasilnyatrue.
Bayangkan method yang dilewati tersebut adalah query database atau pemeriksaan berat — penghematannya nyata, dan yang lebih penting, perilakunya dapat diprediksi: Java memang menjamin operand kanan tidak dieksekusi pada situasi tersebut.
Pola Pemeriksaan Berlapis #
Penggunaan short-circuit yang paling penting sehari-hari adalah guard clause berlapis: periksa dulu bahwa referensi tidak null, baru akses anggotanya. Ekspresi s != null && s.length() > 0 aman karena s.length() hanya dieksekusi bila s sudah terbukti bukan null. Urutan operand di sini bukan gaya penulisan — membaliknya mengubah program yang sehat menjadi program yang berhenti karena NullPointerException.
public class CekNullDahulu {
public static void main(String[] args) {
String nama = "Budi";
String kosong = null;
System.out.println("nama terisi? " + (nama != null && nama.length() > 0));
System.out.println("kosong aman? " + (kosong != null && kosong.length() > 0));
}
}Output yang Dihasilkan:
nama terisi? true
kosong aman? falseBaris 6 memeriksa nama yang berisi teks: kedua operand dievaluasi dan hasilnya true. Baris 7 memeriksa kosong yang bernilai null: operand kiri kosong != null bernilai false, sehingga kosong.length() di operand kanan tidak pernah tersentuh — hasilnya false tanpa exception. Pola yang sama berlaku untuk ||: daftar == null || daftar.isEmpty() mengembalikan true dengan aman ketika daftar memang null.
Operator Tanpa Short-Circuit #
Operator & dan | versi boolean menempuh jalan yang berlawanan: kedua operand selalu dievaluasi tanpa kecuali. Perilaku ini sesekali berguna — ketika kedua operand memang harus menjalankan efek sampingnya — tetapi pada pemeriksaan null justru berbahaya. Program berikut sengaja memakai & pada pola guard yang tadi kita buktikan aman dengan &&.
public class TanpaShortCircuit {
public static void main(String[] args) {
String kosong = null;
// operator & mengevaluasi kedua operand -> NullPointerException
if (kosong != null & kosong.length() > 0) {
System.out.println("terisi");
}
}
}Eksekusi berkas tersebut berakhir dengan NullPointerException — kita verifikasi langsung bahwa pesan yang tercetak berbunyi Cannot invoke "String.length()" because "<local1>" is null, menunjuk pemanggilan kosong.length() pada operand kanan yang seharusnya tidak perlu dievaluasi. Itulah perbedaan konkret antara & yang penurut menghitung semuanya dan && yang tahu kapan harus berhenti.
Dengan short-circuit, petualangan kita menelusuri operator Java tuntas: aritmetika, penugasan, perbandingan, logika, bitwise, shift, unary, ternary, instanceof, prioritas, dan evaluasi hemat. Semua operator ini akan bekerja keras pada Section berikutnya, tempat program kita mulai berbicara dengan dunia luar — membaca input dari pengguna dan mencetak output terformat rapi.
Referensi #
- Java Language Specification — Bab 15 Expressions
- Oracle Dev.java — Learn Java
- Oracle Java SE 25 Documentation
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
CekNullDahulu.java
Unduh berkaspublic class CekNullDahulu {
public static void main(String[] args) {
String nama = "Budi";
String kosong = null;
System.out.println("nama terisi? " + (nama != null && nama.length() > 0));
System.out.println("kosong aman? " + (kosong != null && kosong.length() > 0));
}
}
EfekSamping.java
Unduh berkaspublic class EfekSamping {
static boolean catatPembayaran(int jumlah) {
System.out.println(" -> method catatPembayaran dipanggil: " + jumlah);
return jumlah > 0;
}
public static void main(String[] args) {
System.out.println("Uji && : operand kiri menghasilkan false");
boolean hasil1 = catatPembayaran(0) && catatPembayaran(50000);
System.out.println("hasil1 = " + hasil1);
System.out.println("Uji || : operand kiri menghasilkan true");
boolean hasil2 = catatPembayaran(50000) || catatPembayaran(0);
System.out.println("hasil2 = " + hasil2);
}
}
TanpaShortCircuit.java
Unduh berkaspublic class TanpaShortCircuit {
public static void main(String[] args) {
String kosong = null;
// operator & mengevaluasi kedua operand -> NullPointerException
if (kosong != null & kosong.length() > 0) {
System.out.println("terisi");
}
}
}