Wrap Nullable Java Fields with Optional<T>

Use Optional<T> for fields that may legitimately be missing or null in JSON. Learn the trade-offs between Optional, nullable boxed types, and the @JsonInclude(NON_NULL) approach.

Special Cases

Detailed Explanation

Optional for Nullable JSON Fields

JSON does not distinguish between "missing" and "explicitly null", but Java code often needs to. java.util.Optional<T> is one way to make absence explicit at the type level.

Example JSON

{
  "id": 1,
  "username": "alice",
  "email": "alice@example.com",
  "phone": null
}

Java POJO with Optional

package com.example.model;

import java.util.Optional;

public class User {
    private Integer id;
    private String username;
    private String email;
    private String phone; // store as String

    public Optional<String> getPhone() {
        return Optional.ofNullable(phone);
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
}

Important: Use Optional Only on Getters

The official guidance from the Optional designers (JEP 269) is to not use Optional as a field type. Instead, store a nullable reference and return Optional from the getter. Reasons:

  • Optional is not Serializable
  • Jackson cannot deserialize directly into an Optional field without extra configuration
  • Optional adds a wrapper allocation per access

Configuring Jackson for Optional

If you do choose to use Optional in fields, add the jackson-datatype-jdk8 module:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
ObjectMapper mapper = new ObjectMapper().registerModule(new Jdk8Module());

Alternatives to Optional

  1. Nullable boxed types — the default. Integer instead of int, check for null at the call site.
  2. @JsonInclude(NON_NULL) — exclude null fields from serialization output.
  3. Default values — initialize fields to sensible defaults (e.g., empty list, zero) and never serialize null.

Optional in Records

Records can return Optional from accessor overrides:

public record User(Integer id, String username, String email, String phone) {
    public Optional<String> phone() {
        return Optional.ofNullable(phone);
    }
}

This preserves the canonical constructor while exposing a nullable-aware API.

Use Case

Service-layer code that needs to handle missing data without scattering null checks benefits from Optional return types. API responses with rarely-populated fields (alternate phone, secondary email, custom metadata) are textbook use cases.

Try It — JSON to Java

Open full tool