Java requireNonNullElseGet: สร้าง Default แบบ Lazy และห้าม Supplier คืน null
เมื่อ fallback ต้องอ่าน config หรือสร้าง object ราคาแพง Objects.requireNonNullElseGet จะเรียก supplier เฉพาะตอนค่าหลักเป็น null และรับประกันผลสุดท้ายไม่เป็น null ครับ
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
static String choose(String configured, AtomicInteger calls) {
return Objects.requireNonNullElseGet(configured, () -> {
calls.incrementAndGet();
return "safe-default";
});
}
public static void main(String[] args) {
AtomicInteger calls = new AtomicInteger();
assert choose("custom", calls).equals("custom");
assert calls.get() == 0 : calls.get();
assert choose(null, calls).equals("safe-default");
assert calls.get() == 1 : calls.get();
}
}
ต่างจาก requireNonNullElse(primary, expensiveDefault()) ตรงที่แบบ Else ประเมิน argument ก่อนเข้า method จึงเสียต้นทุนแม้มีค่าหลักแล้ว ส่วน ElseGet เลื่อนงานไว้ใน supplier
ถ้า supplier เองเป็น null หรือคืน null method จะโยน NullPointerException ซึ่งเหมาะเมื่อ contract บอกว่าต้องมีค่าจริง แต่ไม่เหมาะกับ domain ที่ “ไม่มีค่า” เป็นสถานะปกติ กรณีนั้นใช้ Optional หรือ result type ที่สื่อสถานะตรงกว่า
Recap
- ใช้
ElseGetเมื่อ fallback มีต้นทุนหรือ side effect - ทำ supplier ให้คืน non-null ตาม contract
- เทสต์ว่า supplier ไม่ถูกเรียกเมื่อมีค่าหลัก
- ใช้ type ที่สื่อ absence เมื่อ null เป็นสถานะธุรกิจ