0Pricing
Java Academy · Pelajaran

Praktik Terbaik Optional

Terapkan orElse, orElseGet, dan orElseThrow, serta hindari pola penggunaan Optional yang keliru.

Praktik Terbaik Optional adalah pelajaran Java Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Java Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Java Academy mencakup 4 pelajaran total.

Praktik Terbaik Optional

Optional adalah alat yang ampuh jika digunakan dengan benar. Pelajaran ini membahas hal-hal yang boleh dan tidak boleh dilakukan dengan contoh konkret dari basis kode nyata.

Lakukan: Gunakan Optional sebagai Tipe Kembalian

Kasus penggunaan utama Optional adalah sebagai tipe kembalian dari metode yang mungkin tidak menemukan atau menghasilkan nilai.

import java.util.Optional;

// Good: signals to caller that result might be absent
public Optional<User> findByUsername(String username) { ... }
public Optional<Config> getConfig(String key) { ... }
public Optional<String> getHeader(String name) { ... }

// These are all cases where absence is a normal outcome,
// not an exceptional condition

Jangan: Optional sebagai Atribut

Atribut Optional menambah beban tambahan objek dan mempersulit serialisasi. Gunakan nilai kosong atau nilai penanda untuk atribut opsional di dalam kelas.

// BAD
class User {
    private Optional<String> middleName; // wrong
}

// GOOD: use null for absent optional field
class User {
    private final String middleName; // null = absent
    public Optional<String> middleName() {
        return Optional.ofNullable(middleName); // expose as Optional in getter
    }
}
User u = new User(null); // null field
System.out.println(u.middleName().isPresent()); // false

Jangan: Optional sebagai Parameter Metode

Parameter Optional memaksa pemanggil membungkus nilai dalam Optional secara tidak perlu. Gunakan metode berlebih atau @Nullable sebagai gantinya.

// BAD
void sendNotification(String message, Optional<String> subject) { ... }
// caller must write: sendNotification("Hello", Optional.of("News"))

// GOOD: overloading
void sendNotification(String message) { sendNotification(message, null); }
void sendNotification(String message, String subject) {
    // subject may be null
}
// caller writes: sendNotification("Hello", "News") — clean

Jangan: Optional dalam Koleksi

Jangan pernah menempatkan Optional di dalam nilai List, himpunan, atau pemetaan. Optional kosong dalam koleksi tidak bermakna—cukup hilangkan entri tersebut.

// BAD: List of Optionals
List<Optional<User>> results = ...; // meaningless empty Optionals

// GOOD: List of present values only
List<User> presentUsers = maybeUsers.stream()
    .flatMap(Optional::stream)
    .collect(Collectors.toList());

// BAD: Map with Optional values
Map<String, Optional<String>> config = ...;

// GOOD: just use null or omit the key for absent values
Map<String, String> config2 = ...;
String value = config2.getOrDefault("key", "default");

Lakukan: orElseGet untuk Nilai Default yang Mahal

Ketika nilai default melibatkan perhitungan (kueri basis data atau panggilan jaringan), selalu gunakan orElseGet—pemasok hanya dipanggil saat diperlukan.

import java.util.Optional;

// BAD: buildDefault() always called, even when value is present!
String config = getConfig("timeout").orElse(buildDefault());

// GOOD: supplier called lazily only when empty
String config2 = getConfig("timeout").orElseGet(() -> buildDefault());

// Or with method reference:
String config3 = getConfig("timeout").orElseGet(this::buildDefault);

// For cheap literals, orElse is fine
String name = getConfig("name").orElse("default");

Lakukan: orElseThrow untuk Nilai yang Wajib Ada

Ketika nilai yang hilang merupakan kesalahan pemrograman atau pelanggaran invarian, gunakan orElseThrow dengan pengecualian yang deskriptif.

import java.util.Optional;

// Good: throw when absence is an error
User user = userRepository.findById(userId)
    .orElseThrow(() -> new UserNotFoundException("User not found: " + userId));

// Good: in validation code
String apiKey = Optional.ofNullable(System.getenv("API_KEY"))
    .orElseThrow(() -> new IllegalStateException(
        "API_KEY environment variable is required"));

System.out.println("Key found: " + apiKey.length() + " chars");

Antipola: isPresent + get()

Hindari antipola memeriksa isPresent() lalu memanggil get(). Cara ini tidak lebih baik daripada pemeriksaan nilai kosong dan menggagalkan tujuan Optional.

import java.util.Optional;

Optional<String> opt = findValue();

// BAD: isPresent() + get() — no improvement over null check
if (opt.isPresent()) {
    String val = opt.get();
    process(val);
}

// GOOD: use the functional API
opt.ifPresent(this::process);

// GOOD: transform and return
return opt.map(this::process).orElse(null);

// GOOD: provide a default
String result = opt.orElse("default");

Praktik Terbaik Perangkaian

Bangun rangkaian yang rapi: find → filter → transform → fallback. Setiap langkah menjelaskan tujuannya sendiri.

import java.util.Optional;

record User(long id, String plan, boolean active) {}

static Optional<User> findUser(long id) { return Optional.empty(); }

String result = findUser(42L)
    .filter(User::active)           // keep only active users
    .filter(u -> "PRO".equals(u.plan())) // keep only PRO users
    .map(u -> "Welcome, Pro user #" + u.id()) // transform
    .orElse("Upgrade to Pro!");     // fallback

System.out.println(result); // Upgrade to Pro!

Optional di Lapisan Layanan

Contoh lapisan layanan yang realistis dan mengikuti praktik terbaik.

import java.util.Optional;

class OrderService {
    public Optional<OrderSummary> getOrderSummary(long orderId) {
        return orderRepo.findById(orderId)
            .filter(o -> !o.isCancelled())
            .map(this::toSummary);
    }

    public OrderSummary requireOrderSummary(long orderId) {
        return getOrderSummary(orderId)
            .orElseThrow(() -> new OrderNotFoundException(orderId));
    }

    private OrderSummary toSummary(Order o) { return new OrderSummary(o); }
}
// API callers choose: Optional (handle absence) or require (exception)

Optional dan Alat Keamanan Nilai Kosong

Optional melengkapi anotasi @Nullable/@NonNull dan alat seperti SpotBugs/NullAway untuk cakupan keamanan nilai kosong yang lengkap.

// Annotation-based: declares intent for in-class nulls
import org.jetbrains.annotations.*;

class ProductService {
    @Nullable  // may return null — for framework/bean use
    public String getCachedName(String id) { return cache.get(id); }

    // Optional — for service API that handles absence
    public Optional<Product> findProduct(String id) {
        return repo.findById(id);
    }
}
// Use @Nullable for fields/parameters; Optional for return types

Pemeriksaan Singkat

Apa yang keliru dari kode berikut?

if (opt.isPresent()) {
    process(opt.get());
}

Rangkuman: Praktik Terbaik Optional

Hal-hal penting:

  • Gunakan Optional hanya sebagai tipe kembalian—jangan pernah sebagai atribut atau parameter metode
  • Utamakan orElseGet daripada orElse ketika nilai default membutuhkan perhitungan yang mahal
  • Gunakan orElseThrow ketika ketiadaan menunjukkan kesalahan pemrograman
  • Hindari isPresent() + get()—gunakan ifPresent, map, atau orElse sebagai gantinya
  • Jangan pernah menempatkan Optional di dalam koleksi—saring aliran sebagai gantinya
  • Bangun rangkaian yang mudah dibaca: filter → map → orElse untuk alur data yang jelas

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Praktik Terbaik Optional” gratis?

Ya — teks lengkap “Praktik Terbaik Optional” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Java Academy, upgrade ke CoddyKit PRO. Kursus Java Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Praktik Terbaik Optional”?

Terapkan orElse, orElseGet, dan orElseThrow, serta hindari pola penggunaan Optional yang keliru. Kamu berlatih Java Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Java Academy?

Tidak diperlukan pengalaman sebelumnya. Java Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.

Berapa lama pelajaran “Praktik Terbaik Optional” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Java Academy ini?

Ya. Setiap pelajaran Java Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Alasan Optional Ada
  2. Membuat dan Memeriksa Optional
  3. Mengubah Optional: map dan flatMap
  4. Praktik Terbaik Optional
← Kembali ke Java Academy