JAVA

Java Optional

neal89 2025. 4. 4. 13:10

1. Why Optional?

The Problem with null

In Java, null is commonly used to represent the absence of a value. However, misuse or oversight in handling null can easily lead to NullPointerException (NPE), which causes runtime crashes and makes debugging harder.

Drawbacks of null

  • Requires frequent null checks (if (obj != null) {...})
  • Leads to verbose and cluttered code
  • Method signatures don't clearly indicate that null may be returned

The Introduction of Optional

To tackle these issues, Java 8 introduced Optional<T> as a container that may or may not hold a non-null value, helping developers express absence more clearly.

2. Creating Optional Instances

Optional<String> opt1 = Optional.of("Hello");            // Non-null value only
Optional<String> opt2 = Optional.ofNullable(maybeNull);   // May be null
Optional<String> opt3 = Optional.empty();                 // Explicit empty

3. Retrieving Values Safely

  • isPresent() / isEmpty() - Check presence
  • get() - Unsafe, throws exception if empty
  • orElse(T other) - Return value or default
  • orElseGet(Supplier<? extends T>) - Lazily compute default
  • orElseThrow() - Throw custom exception if empty
  • or(Supplier<Optional<T>>) - Provide fallback Optional

4. Functional Methods

  • ifPresent(Consumer<T>) - Run if value exists
  • ifPresentOrElse(Consumer<T>, Runnable) - Run one of two actions
  • map(Function<T,R>) - Transform the value
  • flatMap(Function<T, Optional<R>>) - Flatten nested Optionals
  • filter(Predicate<T>) - Keep value if it matches condition
  • stream() - Return stream with one or no elements

5. Eager vs Lazy Evaluation

  • orElse() evaluates the default value immediately
  • orElseGet() only evaluates if the Optional is empty

Use orElseGet() for expensive computations.

6. Real-World Use Cases

Address Retrieval:

Optional.ofNullable(user)
    .map(User::getAddress)
    .map(Address::getStreet)
    .orElse("Unknown");

Delivery Status:

Optional.ofNullable(order)
    .map(Order::getDelivery)
    .filter(delivery -> !delivery.isCanceled())
    .map(Delivery::getStatus)
    .orElse("Not Delivered");

7. Best Practices

  • ✅ Use Optional for method return values
  • ❌ Do not use Optional for fields or parameters
  • ❌ Do not wrap collections in Optional
  • ❌ Avoid isPresent() + get() combo
  • ✅ Use orElseGet() over orElse() for expensive defaults
  • ❌ Avoid overusing Optional when exceptions are more appropriate

8. Summary Table

 

Concept  Key Idea
Motivation Avoid null, reduce NPEs
Creation of(), ofNullable(), empty()
Access orElse(), orElseGet(), get()
Functional map(), flatMap(), filter(), ifPresent()
Lazy Eval Prefer orElseGet() for expensive operations
Best Practice Use for return types only

'JAVA' 카테고리의 다른 글

Java Parallel Stream and Fork/Join Pattern  (0) 2025.04.04
Default Methods in Java  (0) 2025.04.04
Java Method Reference  (0) 2025.04.02
Java Functional Interfaces  (0) 2025.04.01
Java Annotation  (0) 2025.04.01