if dan else

Membangun percabangan tunggal, berantai, dan bersarang, serta menghindari bug klasik = vs ==.

Daftar isi

Percabangan membuat program memilih jalur yang berbeda untuk masukan yang berbeda, dan pasangan if dengan else adalah bentuknya yang paling dasar di Java. Topik ini menyusun percabangan tunggal, rantai else if, dan percabangan bersarang, lalu menutup dengan jebakan = versus == yang masih lolos ke kode nyata lewat variabel boolean. Setelah membacanya, aturan berupa rentang nilai dan syarat bertingkat dapat diterjemahkan menjadi cabang-cabang yang jelas dan mudah diuji.

Kondisi dan bentuk dasar if#

Kondisi pada if wajib berupa ekspresi bertipe boolean, yakni ekspresi yang nilainya hanya true atau false. Bentuknya bisa berupa perbandingan seperti nilai >= 85, gabungan logika seperti umur >= 17 && punyaKartu, atau variabel boolean itu sendiri. Bila kondisinya true, blok di dalam kurung kurawal dijalankan, sedangkan blok else yang mengikutinya dipilih bila kondisinya false. Bagian else bersifat opsional, sehingga program boleh hanya bereaksi pada satu keadaan dan melanjutkan jalan biasa pada keadaan lain.

Bentuk lengkapnya terlihat seperti berikut.

java Contoh: if dengan else
// tidak-dijalankan
int stok = 3;

if (stok > 0) {
    System.out.println("Barang tersedia");
} else {
    System.out.println("Barang habis");
}

Java tidak mengenal kebenaran selain tipe boolean, sehingga angka, teks, atau objek tidak bisa langsung ditempelkan sebagai kondisi seperti pada sebagian bahasa lain. Aturan ini menutup satu golongan masalah sejak tahap kompilasi, yaitu kondisi yang tanpa sengaja berupa angka atau teks. Konsekuensinya, pemeriksaan pada string harus dinyatakan eksplisit, misalnya if (!nama.isEmpty()) untuk menolak string yang kosong. Kata else selalu berpasangan dengan if terdekat yang belum punya pasangan, aturan yang terasa penting begitu percabangan mulai bersarang.

Rantai else if untuk banyak rentang#

Bila pilihan lebih dari dua, rantai else if menguji kondisi satu per satu dari atas ke bawah. Eksekusi berhenti pada cabang pertama yang cocok, sehingga cabang di bawahnya tidak diuji lagi walaupun kondisinya juga benar. Ujung rantai berupa else tanpa kondisi yang menampung seluruh keadaan yang lolos dari pengujian sebelumnya.

java KlasifikasiNilai.java
public class KlasifikasiNilai {
    public static void main(String[] args) {
        int nilai = 78;

        if (nilai >= 85) {
            System.out.println("Kategori: A");
        } else if (nilai >= 70) {
            System.out.println("Kategori: B");
        } else if (nilai >= 55) {
            System.out.println("Kategori: C");
        } else {
            System.out.println("Kategori: D");
        }
    }
}
text Keluaran
Kategori: B

Nilai 78 gagal pada nilai >= 85, lolos pada nilai >= 70, dan hasilnya Kategori B, sedangkan dua cabang di bawahnya tidak disentuh. Urutan cabang menjadi bagian dari logikanya. Bila nilai >= 55 ditulis paling atas, nilai 78 akan tergolong C karena cabang pertama yang cocok langsung menang. Karena itu, rentang yang saling tumpang tindih ditulis dari batas paling ketat ke yang paling longgar, dan else terakhir berfungsi sebagai jaring pengaman untuk keadaan yang tidak terduga.

Alur if-else if-elseMulaikondisi 1yablok 1tidakkondisi 2yablok 2tidakblok else
Alur rantai if, else if, dan else

Diagram di atas memperlihatkan alur yang sama, yaitu setiap kondisi diuji berurutan dan hanya satu blok yang pernah dijalankan. Setelah blok yang dipilih selesai, eksekusi berlanjut ke pernyataan setelah seluruh rantai, bukan kembali menguji kondisi lain.

Percabangan bersarang#

Sebuah if boleh berada di dalam blok if lain, dan susunan ini disebut percabangan bersarang. Bentuknya tepat ketika keputusan kedua hanya relevan setelah keputusan pertama lolos, misalnya memeriksa tiket berlaku lebih dahulu, baru menentukan gerbang dari nomor kursi. Keputusan yang tidak saling bergantung sebaiknya tidak dipaksa bersarang, karena setiap tingkat menambah satu indentasi yang harus diikuti pembaca.

java Contoh: if di dalam if
// tidak-dijalankan
if (tiketBerlaku) {
    if (nomorKursi % 2 == 0) {
        System.out.println("Gerbang A");
    } else {
        System.out.println("Gerbang B");
    }
} else {
    System.out.println("Tiket tidak berlaku");
}

Pada contoh di atas, pemeriksaan nomor kursi hanya dijalankan bila tiketnya sah, sehingga kedua keputusan memang bertingkat. Masalah muncul ketika bersarang dipakai untuk kondisi yang sebenarnya sejajar, karena tingkat yang menumpuk membuat jalur else-nya sulit dipetakan. Aturan praktisnya, percabangan yang sudah melewati dua tingkat biasanya lebih jelas dipecah menjadi metode tersendiri, sehingga tiap metode menjawab satu pertanyaan.

Jebakan = versus ==#

Operator = menugaskan nilai ke variabel, sedangkan == membandingkan dua nilai. Kesalahan menukar keduanya di dalam kondisi adalah bug klasik yang diwariskan bahasa C ke banyak bahasa lain. Java menutup sebagian besar celah itu karena kondisi if wajib boolean, sehingga if (nilai = 78) ditolak kompiler dengan pesan incompatible types: int cannot be converted to boolean. Celah yang tersisa ada pada variabel boolean itu sendiri, karena hasil penugasan aktif = true juga bertipe boolean dan bernilai true, sehingga baris ini sah menurut kompiler.

java CekAktif.java
public class CekAktif {
    public static void main(String[] args) {
        boolean aktif = false;

        if (aktif = true) {
            System.out.println("Cabang dijalankan, aktif sekarang: " + aktif);
        }
    }
}
text Keluaran
Cabang dijalankan, aktif sekarang: true

Variabel aktif dideklarasikan false, tetapi cabang tetap dijalankan dan nilainya ikut berubah menjadi true. Tidak ada pesan error, tidak ada peringatan dari kompiler bawaan, dan pola ini biasanya hanya ditandai oleh editor atau alat analisis statis yang mengenali penugasan di dalam kondisi. Perbandingan eksplisit aktif == true sebenarnya sah, tetapi berlebihan, karena kondisi boolean ditulis langsung sebagai if (aktif), sedangkan pembalikannya menjadi if (!aktif).

Kesalahan umum#

  • Menukar = dengan == pada variabel boolean, seperti if (aktif = true). Program tetap berjalan, tetapi nilai variabelnya ikut berubah dan cabang yang dipilih menyesatkan. Tulis if (aktif) atau if (!aktif).
  • Menaruh titik koma setelah kondisi, misalnya if (stok > 0);. Titik koma itu menjadi badan if yang kosong, sehingga blok kurung kurawal di bawahnya selalu dijalankan apa pun kondisinya.
  • Menulis rentang pada rantai else if dari yang paling longgar. Nilai tinggi tergolong ke kategori bawah karena cabang pertama yang cocok langsung dipakai. Susun rentangnya dari batas paling ketat.
  • Membuang kurung kurawal untuk badan if satu baris. Hanya pernyataan pertama yang terikat pada kondisinya, sedangkan pernyataan setelahnya selalu dijalankan dan kesalahannya sulit terlihat.
  • Lupa bahwa else berpasangan dengan if terdekatnya pada percabangan bersarang, bukan dengan if terluar yang tampak sejajar. Kurung kurawal dan indentasi yang konsisten membuat pasangan itu tidak salah baca.
  • Membandingkan isi String dengan == di dalam kondisi. Operator itu membandingkan referensi, bukan isinya, sehingga perbandingan teks memakai metode equals.

Ringkasan#

  • Kondisi if wajib bertipe boolean, dan bagian else bersifat opsional.
  • Rantai else if menguji kondisi dari atas ke bawah dan berhenti pada cabang pertama yang cocok, sehingga urutan rentangnya menentukan hasil.
  • Percabangan bersarang tepat untuk keputusan yang memang bertingkat, sedangkan kondisi yang sejajar lebih jelas digabung dengan &&.
  • Penugasan = di dalam kondisi bertipe boolean lolos dari kompiler, sehingga kondisi boolean ditulis langsung sebagai if (aktif) dan bukan if (aktif == true).

Referensi#