Fundamentals 7 min read

How Java’s New Null‑Restricted Types Aim to Eradicate NullPointerExceptions

This article explains Java’s preview Null‑Restricted and Nullable type system, showing how the new syntax (Foo! and Foo?) lets developers explicitly declare nullability, improves compile‑time safety, integrates with existing code, and compares the approach to TypeScript’s ! and ? operators.

macrozheng
macrozheng
macrozheng
How Java’s New Null‑Restricted Types Aim to Eradicate NullPointerExceptions

Feature Overview

Java developers have long struggled with

null

handling because the language cannot explicitly express that a variable will never be

null

, leading to pervasive NullPointerException risks.

To address this, Java introduces a preview feature called Null‑Restricted and Nullable types. These allow developers to declare whether a type may hold

null

values, providing stronger compile‑time and runtime safety.

Foo!

– a non‑null‑restricted type;

null

is not an acceptable value.

Foo?

– a nullable type;

null

is explicitly allowed.

Foo

– unspecified nullability; the compiler does not know whether

null

is permitted.

Feature Highlights

Explicit null‑value constraints : Use

Foo!

to forbid

null

and

Foo?

to allow it, while the default

Foo

remains ambiguous.

Compatibility with existing code : The feature can be introduced gradually without breaking legacy Java code or standard libraries.

Automatic detection and warnings : The compiler inserts runtime checks when converting between nullable and non‑nullable types, warning about potential

null

misuse.

Strict initialization of fields and arrays : Nullable fields or arrays must be initialized before read, otherwise an exception is thrown (e.g.,

String![] labels

requires each element to be set).

Flexible nullness conversion : Types can be converted similarly to boxing/unboxing, with runtime checks for unsafe conversions.

Future Outlook

Although still in preview, the feature promises broader adoption across APIs, potentially allowing entire classes or modules to default to null‑restricted behavior, further strengthening Java’s robustness.

Comparison with TypeScript

In TypeScript, the

!

and

?

symbols serve different purposes:

! – Non‑null assertion

The

!

operator tells the compiler that a variable is definitely not

null

or

undefined

, even if static analysis cannot prove it.

<code>let name: string | null = "Alice";
console.log(name!.toUpperCase()); // non‑null assertion, assumes name is not null</code>

If the value is actually

null

at runtime, an error may still occur.

? – Optional property/parameter

The

?

marker declares that a property or parameter may be omitted or be

undefined

.

<code>interface Person {
  name: string;
  age?: number; // optional property
}

const alice: Person = { name: "Alice" }; // age can be omitted
</code>

Reference

Java preview feature – Null‑Restricted and Nullable Types: https://openjdk.org/jeps/12

Javatype-systemprogramming languagesNull SafetyPreview Feature
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.