skip to content

Optional Construction & Query

Optional.of rejects null, ofNullable accepts it, empty gives you the absent case, and get throws when there is nothing there. Interviewers ask why calling get without checking is barely better than dereferencing a null.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

5

What are the three ways to create an Optional in Java, and when do you use each?

level: juniorimportance: must knowfreq 78%

answer

  1. of = non-null, throws NPE on null
  2. ofNullable = safe wrapper, empty on null
  3. empty = deliberate no-value (shared singleton)
  4. of(map.get(key)) is the classic bug → use ofNullable

basics

~10 s

Optional.of(x) wraps a value you know is not null; Optional.ofNullable(x) wraps a value that might be null and gives empty if it is null; Optional.empty() makes an empty Optional with no value.

solid answer

~40 s

There are three factory methods. Optional.of(value) creates an Optional holding the value, but throws NullPointerException immediately if you pass null, so use it only when you are certain the value is non-null. Optional.ofNullable(value) is the safe wrapper: if the argument is non-null it behaves like of, and if it is null it returns an empty Optional, so it's what you reach for around legacy or nullable sources such as a map lookup or a nullable field. Optional.empty() returns a shared empty instance representing no value, used as a base case or when you explicitly want to signal absence. The rule of thumb: of when non-null is guaranteed (fail fast on a bug), ofNullable when null is possible, empty for the deliberate no-value case.

code

java · 9 lines
java
String known = "hello";
Optional<String> a = Optional.of(known);          // holds "hello"
Optional<String> b = Optional.ofNullable(null);   // empty, no exception
Optional<String> c = Optional.empty();            // empty

// The classic bug: Map.get can return null
Map<String, String> m = new HashMap<>();
// Optional<String> wrong = Optional.of(m.get("x"));        // throws NPE
Optional<String> right = Optional.ofNullable(m.get("x"));    // empty

go deeper

for a junior

Name the three factories and state of throws on null, ofNullable is safe, empty is the no-value case.

for a middle

Explain the choose-by-intent rule and identify Optional.of(map.get(key)) as a bug, with ofNullable as the fix.

for a senior

Discuss fail-fast semantics of of (surfacing bugs at the source), empty() being a cached singleton, and Optional as a value-based, immutable type.

for a principal

Frame Optional as an API-design tool for making absence explicit at type boundaries; advise of for invariants/postconditions and ofNullable at integration seams with nullable/legacy code.

## What an Optional is In Java, a variable of a reference type (like `String` or `Customer`) can hold either an object or the special value `null`, meaning "nothing here." Calling a method on `null` throws a `NullPointerException` (NPE) at runtime. `Optional<T>` is a small container (a box) that holds *either* one value of type `T` or *nothing*. Its purpose is to make "this might be absent" visible in the type itself, so callers are reminded to handle the empty case instead of forgetting and hitting an NPE. An Optional is **immutable** (you can't change what's inside once created) and is a **value-based class** (don't synchronize on it or compare with `==`). ## The three factory methods (constructors) You never use `new Optional(...)`; the constructor is private. You create one through three static factory methods: 1. **`Optional.of(value)`** — Creates an Optional that contains `value`. If `value` is `null`, it throws a `NullPointerException` *right then*, on the line that calls `of`. Use this only when you are sure the value is non-null. Throwing early is actually helpful: it surfaces a programming bug at its source rather than letting a `null` travel deep into your code. 2. **`Optional.ofNullable(value)`** — The defensive version. If `value` is non-null it behaves exactly like `of`. If `value` is `null` it returns an *empty* Optional instead of throwing. This is the method you use whenever the source could legitimately be null: a `Map.get`, a field that may be unset, a result from older code that uses null to mean "not found." 3. **`Optional.empty()`** — Returns an Optional containing nothing. Internally Java returns a single shared empty instance (a cached singleton), so this is cheap. Use it as a base case, a default, or when you deliberately want to express "no value." ## How to choose - You **know** it's non-null (e.g., you just constructed it): use `of`. You *want* an NPE if it's somehow null, because that would mean a bug. - It **might** be null: use `ofNullable`. This is the single most common safe choice when bridging nullable code into the Optional world. - You want an explicit empty: use `empty()`. ## Common mistake Writing `Optional.of(map.get(key))` is a frequent bug: `Map.get` returns `null` when the key is missing, so `of` throws an NPE — exactly the situation Optional was meant to prevent. The correct call is `Optional.ofNullable(map.get(key))`. ## Tiny example ```java String known = "hello"; Optional<String> a = Optional.of(known); // holds "hello" Optional<String> b = Optional.ofNullable(null); // empty, no throw Optional<String> c = Optional.empty(); // empty // Optional.of(null); // throws NullPointerException ``` With these three you can wrap any source — guaranteed-present, maybe-null, or deliberately-absent — into the same container type, and downstream code handles all of them uniformly.

  • Why does Optional.of throw on null instead of just returning empty like ofNullable?
    Because of expresses the contract "this value must be present." If it's null, that's a programming error, and failing fast at the call site makes the bug easy to locate. ofNullable exists precisely for the case where null is a legitimate possibility.
  • Is Optional.empty() a new object each time?
    No. It returns a single shared, cached empty instance, so calling it repeatedly is cheap and creates no garbage.

Think of three ways to fill a single-item box: of insists the box is never empty and shouts if you try to put nothing in; ofNullable quietly leaves the box empty if you hand it nothing; empty hands you an already-empty box.

saying these in an interview costs you the question

  • Saying Optional.of(null) returns an empty Optional — it throws NPE
  • Using Optional.of on a value that could be null (e.g. map.get) when ofNullable is needed
  • Thinking you create an Optional with new Optional<>() — the constructor is private
  • Claiming all three factories are interchangeable

context

open as a page

What does Optional.get() do when the Optional is empty, and why is calling get() directly discouraged?

level: middleimportance: must knowfreq 70%

basics

~20 s

get() returns the value if one is present, but throws NoSuchElementException if the Optional is empty. Calling it directly is risky because you can forget to check first, so prefer orElse, orElseThrow, or ifPresent instead.

open as a page

How do you check whether an Optional contains a value, and what changed in Java 11?

level: juniorimportance: should knowfreq 62%

basics

~20 s

Use isPresent() to ask if a value is there (returns true if present) and isEmpty() to ask if it is missing (returns true if empty). isEmpty() was added in Java 11 and is just the opposite of isPresent().

open as a page

What is the difference between orElse and orElseGet, and why can it matter for correctness, not just performance?

level: seniorimportance: should knowfreq 55%

basics

~20 s

orElse(x) always builds x even when the Optional has a value; orElseGet(supplier) only runs the supplier when the Optional is empty. So orElseGet avoids wasted work, and matters when the default is expensive or has side effects.

open as a page

As an API designer, where should Optional appear and where should it be avoided, and how do construction choices reflect those decisions?

level: principalimportance: nice to knowfreq 40%

basics

~20 s

Use Optional mainly as a method return type to signal a value might be missing. Avoid it for fields, method parameters, and collections (return an empty collection instead). Use Optional.of when you guarantee non-null and ofNullable at the boundary where null can come in.

open as a page