Back to IF2010 Pemrograman Berorientasi Objek

Topic

Questions/Cues

  • Apa itu Assertion?
  • Dua Bentuk assert
  • Mengaktifkan Assertion
  • Perbandingan dengan C++
  • Kapan Sebaiknya Menggunakan assert?
  • Invariant Internal & Alur Kontrol
  • Preconditions, Postconditions, Class Invariants
  • Kapan TIDAK Boleh Menggunakan assert?
  • Apa itu Exception?
  • Blok try-catch-finally
  • try-with-resources
  • throw dan throws
  • Chained Exceptions
  • Hirarki Throwable
  • Checked vs. Unchecked Exception
  • Membuat Exception Sendiri

Assertion

  • Sebuah statement untuk menguji asumsi tentang program kita. Berisi ekspresi boolean yang diyakini true. Jika false, sistem akan melempar AssertionError.
  • Tujuan: Mendeteksi bug lebih awal, meningkatkan keyakinan pada kode, dan berfungsi sebagai dokumentasi internal.

Dua Bentuk Assertion Statement:

  1. assert Expression1;
    • Bentuk sederhana. Jika Expression1 bernilai false, AssertionError dilempar tanpa pesan detail.
    • Contoh: assert (speed < 300000);
  2. assert Expression1 : Expression2;
    • Expression2 adalah sebuah nilai yang akan disertakan dalam pesan error untuk memberikan informasi lebih detail.
    • Contoh: assert (speed < 300000) : "kecepatan melebihi kecepatan cahaya";

Mengaktifkan Assertion:

  • Secara default, JVM tidak memeriksa assert. Untuk mengaktifkannya, program harus dijalankan dengan flag -ea (enable assertions).
  • Contoh: java -ea NamaKelas

Perbandingan dengan assert di C++:

  • Di C++, assert adalah sebuah macro dari <cassert>.
  • Jika ekspresi false, pesan error ditulis ke standard error dan program dihentikan (abort() dipanggil).
  • Dapat dinonaktifkan dengan mendefinisikan macro NDEBUG sebelum #include <assert.h>.
  • Dirancang untuk menangkap kesalahan pemrograman, bukan kesalahan pengguna atau runtime.

Kapan Sebaiknya Menggunakan assert?

  • Internal Invariants: Untuk memastikan asumsi internal tentang state program selalu benar. Contoh: Pada sebuah else clause yang seharusnya secara logika pasti benar

    if (i % 3 == 0) { ... } 
    else if (i % 3 == 1) { ... } 
    else { 
    		assert i % 3 == 2; 
    		... 
    }
  • Control-Flow Invariants: Untuk memastikan alur program berjalan sesuai asumsi. Contoh: Pada default case dari switch yang seharusnya tidak pernah tercapai.

    switch(suit) {
    		// ... case lain
    		default: 
    				assert false; // Seharusnya tidak pernah sampai sini
    }
  • Preconditions, Postconditions, dan Class Invariants:

    • Preconditions (Method Non-Publik): Untuk memvalidasi kondisi pada method private atau protected, di mana kita sebagai penulis kelas mengontrol semua pemanggilnya.
    • Postconditions: Untuk memverifikasi hasil dari sebuah komputasi sebelum dikembalikan.
    • Class Invariants: Untuk memastikan properti sebuah objek selalu konsisten (misal: nilai menit pada jam selalu antara 0-59).

Kapan TIDAK Boleh Menggunakan assert?

  • Pengecekan Argumen Method Publik: Gunakan if-then-throw untuk melempar exception yang sesuai (misal: IllegalArgumentException). Ini adalah bagian dari kontrak API dan harus selalu aktif.
  • Melakukan Aksi Program: Ekspresi dalam assert tidak boleh memiliki side effects atau melakukan pekerjaan yang penting bagi program, karena assert bisa dinonaktifkan.
    • Salah: assert names.remove(null);

    • Benar:

      boolean nullsRemoved = names.remove(null);
      assert nullsRemoved;

Exception

Sebuah event yang mengganggu alur normal program. Saat error terjadi, method membuat exception object dan melemparkannya (throw) ke runtime system. Objek ini adalah turunan dari kelas Throwable dan berisi informasi tentang error tersebut.

  • Blok try-catch-finally:

    • try: Membungkus kode yang berpotensi melempar exception.
    • catch: Menangkap dan menangani exception dengan tipe tertentu. Sebuah blok try bisa diikuti oleh beberapa blok catch untuk menangani berbagai tipe exception.
    • finally: Blok kode yang pasti akan dieksekusi, baik terjadi exception maupun tidak. Berguna untuk membersihkan resource (seperti menutup file atau koneksi).
  • try-with-resources (Java 7+):

    • Menyederhanakan blok try-catch-finally untuk resource yang harus ditutup. Resource (yang mengimplementasikan AutoCloseable) dideklarasikan dalam try(...) dan akan ditutup secara otomatis.
    try (PrintWriter out = new PrintWriter(new FileWriter("out.txt"))) {
    		// ... gunakan 'out'
    } // 'out' akan otomatis di-close() di sini
  • throw dan throws:

    • throw: Statement untuk melempar sebuah exception object.
    • throws: Keyword dalam signature method yang mendeklarasikan bahwa method tersebut mungkin melempar checked exception tertentu.
  • Chained Exceptions:

    • Mekanisme untuk menangkap sebuah exception, lalu melempar exception baru sambil menyertakan exception asli sebagai penyebabnya. Berguna untuk menambahkan konteks atau menerjemahkan exception tingkat rendah menjadi exception yang lebih relevan.
  • Hirarki Throwable:

    • Error: Masalah serius yang umumnya tidak ditangani oleh aplikasi (misal: OutOfMemoryError). Bersifat unchecked.
    • Exception: Kondisi yang mungkin ingin ditangani aplikasi.
      • RuntimeException: Turunan Exception yang bersifat unchecked (misal: NullPointerException, IndexOutOfBoundsException). Biasanya disebabkan oleh bug pemrograman.
      • Exception Lain (Checked): Turunan Exception selain RuntimeException. Compiler memaksa kita untuk menanganinya (dengan try-catch) atau mendeklarasikannya (dengan throws). Contoh: IOException, SQLException.
  • Membuat Exception Sendiri:

    • Bisa membuat kelas exception kustom dengan mewarisi dari Exception (untuk checked) atau RuntimeException (untuk unchecked).
    • Alasan: Menyediakan informasi error yang lebih spesifik, memudahkan pengguna library kita, dan mengelompokkan error yang berhubungan.

Summary

Assertion dan Exception adalah dua mekanisme fundamental untuk menciptakan program yang robust. Assertion (assert) berfungsi sebagai alat bantu development untuk memvalidasi asumsi internal programmer yang dapat dinonaktifkan di lingkungan produksi. Sebaliknya, Exception (dengan blok try-catch-finally dan try-with-resources) adalah mekanisme runtime yang integral untuk menangani kondisi error yang bisa terjadi, memisahkan logika penanganan error dari alur utama program, dan dikategorikan sebagai checked (wajib ditangani) atau unchecked (biasanya bug pemrograman).