Belajar OOP dengan Java - Enum, Record & Sealed Class
Series/Belajar OOP/Episode 10
Episode 10 of 23

Belajar OOP dengan Java - Enum, Record & Sealed Class

Mengenal tiga fitur Java modern yang mereduksi boilerplate: enum dengan field dan method plus switch pattern matching, record sebagai data carrier immutable otomatis, dan sealed class/interface untuk hierarki tertutup yang aman terhadap lupa kasus.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Sejauh ini kita bekerja dengan class klasik: banyak baris untuk sesuatu yang sebenarnya sederhana. Episode ini memperkenalkan tiga fitur Java modern yang membuat OOP jauh lebih ekspresif: enum untuk kumpulan nilai terbatas, record untuk data immutable, dan sealed class untuk hierarki tertutup.

Mengapa ketiganya revolusioner? Karena mereka mengubah bahasa dari verbose menjadi expressive — mengekspresikan maksud kode secara langsung, bukan lewat pola yang harus diingat. Java 21+ menyatukan ketiganya dengan pattern matching sehingga kode menjadi lebih pendek, lebih jelas, dan lebih aman.

Enum: Kumpulan Nilai Terbatas

Dasar Enum

enum merepresentasikan kumpulan konstanta yang terbatas dan dikenal — status pesanan, tipe kartu, level akses:

JavaEnum dasar
public enum Status {
    MENUNGGU,
    DIPROSES,
    SELESAI,
    DIBATALKAN
}
java
Status status = Status.SELESAI;

Sebelum enum ada (Java 5), orang menulis konstanta public static final int STATUS_SELESAI = 2 — yang rawan salah nilai dan tidak type-safe. Enum menyelesaikan keduanya: nilai salah akan ditolak compiler.

Enum dengan Field dan Method

Enum bukan sekadar label — ia bisa membawa state dan perilaku:

JavaEnum dengan field dan method
public enum TipeKartu {
    DEBIT(1.0),
    KREDIT(2.5),
    PREMIUM(0.5);
 
    private final double biayaPersen;
 
    TipeKartu(double biayaPersen) {
        this.biayaPersen = biayaPersen;
    }
 
    public double hitungBiaya(double nominal) {
        return nominal * biayaPersen / 100;
    }
}

Pemakaian: TipeKartu.KREDIT.hitungBiaya(100000). Setiap konstanta enum adalah object — dengan state (biayaPersen) dan behavior (hitungBiaya). Ini OOP dalam bentuk terkecil.

Switch Pattern Matching

Sejak JDK 21, switch atas enum (dan tipe lain) bisa menggunakan pattern matching dengan ekspresi:

JavaSwitch expression atas enum
public String label(Status status) {
    return switch (status) {
        case MENUNGGU -> "Menunggu pembayaran";
        case DIPROSES -> "Sedang dikemas";
        case SELESAI -> "Telah terkirim";
        case DIBATALKAN -> "Dibatalkan";
    };
}

Perhatikan: switch sebagai ekspresi (mengembalikan nilai), panah -> tanpa break, dan jika enum bersifat sealed/enum, compiler memastikan semua kasus tercakup. Detail ini akan terasa saat kita menggabungkan dengan sealed class di bawah.

Record: Data Carrier Immutable

Masalah Class Data

Class yang hanya membawa data membutuhkan banyak boilerplate: constructor, getter, equals, hashCode, toString — semuanya formulaik dan rawan error (terutama equals). Record menghilangkan semuanya:

JavaRecord menghilangkan boilerplate
public record Alamat(String jalan, String kota, String kodePos) {}

Satu baris menghasilkan: constructor penuh, getter (jalan(), kota(), kodePos()), equals(), hashCode(), dan toString() — semuanya otomatis. Semua komponen private final — record immutable sejak lahir.

JavaRecord dalam penggunaan
public class Main {
    public static void main(String[] args) {
        Alamat a1 = new Alamat("Jl. Merdeka", "Jakarta", "10110");
        Alamat a2 = new Alamat("Jl. Merdeka", "Jakarta", "10110");
        System.out.println(a1);                    // Alamat[jalan=Jl. Merdeka, kota=Jakarta, kodePos=10110]
        System.out.println(a1.equals(a2));         // true
        System.out.println(a1.kota());             // Jakarta
    }
}

equals otomatis membandingkan semua komponen — masalah yang menyakitkan jika ditulis manual. Record juga mendukung compact constructor (dari episode 5) untuk validasi.

Record dan Pola Lama

Pola lamaPengganti record
Class data + getter + equals + hashCode + toStringRecord (satu baris)
JavaBeans yang diisi setter bertahapRecord dengan constructor penuh
DTO yang disalin antar lapisanRecord immutable

Karena immutable dan auto-equals, record menjadi pilihan default untuk DTO (data transfer object) — persis yang dipakai framework modern dan Optional di episode 13.

Sealed Class: Hierarki Tertutup

Dasar Sealed Class

sealed membatasi siapa yang boleh menjadi subclass. Ini "closed hierarchy" untuk kasus yang memang seharusnya tertutup:

JavaSealed class dengan permits
public sealed class Bentuk permits Lingkaran, Persegi, Segitiga {}
JavaSubclass yang diizinkan
public final class Lingkaran extends Bentuk {
    double jariJari;
}
 
public final class Persegi extends Bentuk {
    double sisi;
}
 
public final class Segitiga extends Bentuk {
    double alas, tinggi;
}

Setiap subclass yang di-permits wajib salah satu dari: final, sealed, atau non-sealed. Class lain yang mencoba extends Bentuk akan error compile.

Kekuatan Kombinasi: Sealed + Pattern Matching

Keuntungan sebenarnya muncul saat dipadukan dengan switch pattern matching. Karena compiler tahu persis subclass apa saja yang ada, ia bisa memastikan semua kasus ditangani:

JavaExhaustive switch atas sealed class
public double luas(Bentuk bentuk) {
    return switch (bentuk) {
        case Lingkaran l -> Math.PI * l.jariJari * l.jariJari;
        case Persegi p -> p.sisi * p.sisi;
        case Segitiga s -> 0.5 * s.alas * s.tinggi;
    };
}

Jika besok ada subclass baru Trapesium ditambahkan ke permits, compiler langsung memaksa kalian menambah case di sini — tidak mungkin lupa. Ini momen "dengan pattern matching, compiler jadi rekan" yang akan kita pakai lagi di episode 13 dan 19.

Kapan Sealed, Kapan Tidak?

Sealed cocok ketika domain matematis/terbatas: bentuk geometri, AST (abstract syntax tree) bahasa, jenis message dalam protokol. Sealed tidak cocok untuk domain yang tumbuh cepat dan terbuka — di sana interface biasa (open hierarchy) lebih fleksibel.

Warning

Jangan langsung membungkus seluruh model dengan sealed. Sealed adalah keputusan desain yang disengaja: ia menukar fleksibilitas (tidak ada subclass baru tanpa edit) dengan keamanan (compiler menjamin kelengkapan). Gunakan saat hierarki memang kecil dan stabil.

Latihan Terpadu

JavaEnum + record + sealed bekerja sama
public enum JenisNotifikasi { EMAIL, SMS, PUSH }
 
public sealed interface Notifikasi permits EmailNotif, SmsNotif, PushNotif {
    String format();
}
 
public record EmailNotif(String alamat, String isi) implements Notifikasi {
    public String format() {
        return "EMAIL ke " + alamat + ": " + isi;
    }
}
 
public record SmsNotif(String nomor, String isi) implements Notifikasi {
    public String format() {
        return "SMS ke " + nomor + ": " + isi;
    }
}
 
public record PushNotif(String perangkat, String isi) implements Notifikasi {
    public String format() {
        return "PUSH ke " + perangkat + ": " + isi;
    }
}

Tiga fitur saling melengkapi: enum untuk kategori, record untuk data immutable per jenis, sealed untuk hierarki yang pasti. Pemakai tinggal memanggil format() secara polymorphic (episode 8) tanpa cabang.

Tip

Rule of thumb Java modern: record untuk data, enum untuk kumpulan terbatas, sealed untuk hierarki tertutup. Jika class kalian "hanya bawa data", itu record. Jika hanya kumpulan konstanta, itu enum. Jika subclass jumlahnya sudah jelas di kepala, pertimbangkan sealed.

Penutup

Inti yang harus dibawa pulang:

  • Enum: kumpulan nilai terbatas dengan state & behavior; cocok dengan switch expression.
  • Record: data carrier immutable otomatis — constructor, getter, equals, hashCode, toString gratis.
  • Sealed class/interface: hierarki tertutup; compiler memaksa kelengkapan saat switch pattern matching.
  • Kombinasi ketiganya menghasilkan kode yang singkat, jelas, dan type-safe.

Di episode 11 selanjutnya kita akan membahas generics & collections — type parameter, bounded wildcards, type erasure, lalu List, Set, dan Map dari Java Collections Framework. Sampai jumpa di episode 11!

Belajar OOP dengan Java - Enum, Record & Sealed Class | Belajar OOP