Fundamentals 11 min read

Why Java’s Ternary Operator Can Throw NPE: Autoboxing Pitfalls Explained

The article explains how Java’s ternary operator can cause NullPointerException when type inference leads to automatic unboxing of a null wrapper, demonstrates this with concrete code examples, decompiled bytecode, and offers strategies such as using consistent types or replacing the ternary with if‑else.

Shepherd Advanced Notes
Shepherd Advanced Notes
Shepherd Advanced Notes
Why Java’s Ternary Operator Can Throw NPE: Autoboxing Pitfalls Explained

Background

During integration testing a feature, a NullPointerException appeared only in the test environment. The failing line was:

user.setIsAdmin(Objects.isNull(org) ? 0 : org.getIsAdmin());
user.setIsMask(Objects.isNull(org) ? 0 : org.getIsMask());

The first line succeeded, the second threw NPE because org was null and org.getIsMask() returned null, triggering automatic unboxing.

Autoboxing and Unboxing

Since JDK 1.5 Java automatically converts between primitive types and their wrapper classes. Autoboxing wraps a primitive into its wrapper, e.g.:

int a = 5;
Integer b = a; // autoboxing

Autoboxing uses Integer.valueOf(), which benefits from a cache for values –128 to 127, allowing == comparison within that range. Unboxing converts a wrapper back to a primitive, e.g.:

Integer a = 5; // autoboxing
int b = a; // unboxing

Unboxing is performed by calling the wrapper’s xxxValue() method (e.g., intValue()), and if the wrapper reference is null a NullPointerException is thrown.

Ternary Operator

The ternary syntax is result = condition ? value1 : value2;. The compiler infers a common result type from value1 and value2. When the inferred type is a wrapper and one branch is null while the other is a primitive, the compiler inserts an unboxing conversion for the null branch, causing NPE at runtime.

3.1 Mixed wrapper and primitive (result is wrapper)

boolean flag = true;
Integer result;
Integer value1 = null;
int value2 = 8;
result = flag ? value1 : value2;

Running this code throws java.lang.NullPointerException. Decompiling shows the compiler generated value1.intValue(), i.e., an unboxing of null.

3.2 Both branches primitive (result is wrapper)

boolean flag = true;
Integer result;
int value1 = 6;
int value2 = 8;
result = flag ? value1 : value2;

Result is 6 and no exception occurs. Decompiled code shows the primitive value is boxed after the conditional.

3.3 Both branches wrapper (result is wrapper)

boolean flag = true;
Integer result;
Integer value1 = null;
Integer value2 = 8;
result = flag ? value1 : value2;

Result is null; no exception because no unboxing is required.

3.4 All primitives (result is primitive)

boolean flag = true;
int result;
int value1 = 6;
int value2 = 8;
result = flag ? value1 : value2;

Result is 6; primitives cannot be null, so no NPE.

3.5 Result primitive, branches wrapper

boolean flag = true;
int result;
Integer value1 = null;
Integer value2 = 8;
result = flag ? value1 : value2;

Running throws NPE because the compiler unboxes value1 to int.

3.6 Result primitive, mixed branches

boolean flag = true;
int result;
Integer value1 = null;
int value2 = 8;
result = flag ? value1 : value2;

Again a NullPointerException occurs due to unboxing of the null wrapper.

Conclusion: Whenever the three involved types differ and an automatic unboxing of a null wrapper occurs, a NullPointerException is produced.

Solution

To avoid the NPE:

Ensure both branches of the ternary operator have the same type (both primitives or both wrappers).

Prefer using if‑else when a wrapper may be null, e.g.:

Integer a = null;
Integer result = (a != null) ? a : Integer.valueOf(0);
// or
Integer result;
if (a != null) {
    result = a;
} else {
    result = Integer.valueOf(0);
}

These approaches prevent the compiler from inserting an unwanted unboxing conversion.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaautoboxingNullPointerExceptiontype inferenceternary operator
Shepherd Advanced Notes
Written by

Shepherd Advanced Notes

Dedicated to sharing advanced Java technical insights, daily work snippets, and the power of persistent effort.

0 followers
Reader feedback

How this landed with the community

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.