← Debugging Guides

阅读中文版本

Java — NullPointerException with a helpful message

Locate the null source of a NullPointerException by using helpful messages, stack traces and defensive access.

beginnerdebuggingjavajvm

Symptoms

  • java.lang.NullPointerException: Cannot invoke "String.length()" because "name" is null
  • A method throws NPE only for some inputs
  • The NPE appears deep in a library call chain
  • Autoboxing or chained calls hide the null source

Possible causes

  • A reference was never initialized or was assigned null
  • A method returned null where the caller assumed a value
  • A collection lookup or map get returned null
  • Autounboxing a null wrapper type

Diagnosis steps

Read the helpful NPE message

java -XX:+ShowCodeDetailsInExceptionMessages App 2>&1 | head

Interpretation

Modern JVMs name the expression and variable that was null, which usually points straight at the source.

Trace the value origin with the stack

cat hs_err_pid*.log 2>/dev/null ; App 2>&1 | grep -A2 NullPointer

Interpretation

The top frames show where the null was dereferenced; walking up reveals which call produced it.

Guard or fail fast with a clear message

Objects.requireNonNull(input, "input must not be null")

Interpretation

Failing at the boundary with a message moves the error closer to the cause and away from the symptom.

Root cause

A reference used at the failing point was null, typically because an earlier call returned null or a field was never set, and the code assumed a value was present.

Fix

Validate inputs with requireNonNull or Optional at boundaries, return empty collections instead of null, and use annotations to make nullability explicit so the compiler and tools can warn.

Verify the fix

Rerun the failing path and confirm it either succeeds or fails with the intended validation message at the correct boundary rather than deep in the stack.

Symptom walkthrough

The application throws NullPointerException, and with a modern JDK the message names the exact expression that was null, for example Cannot invoke String.length() because name is null. The same code may pass for some inputs and fail for others, which means a value that is often present is sometimes absent. Chained calls and autoboxing can hide which part returned null.

Fix in practice

Use requireNonNull or Optional at API boundaries so the failure happens where the bad value enters, and return empty collections rather than null to reduce null checks. Nullability annotations let static analysis flag risky dereferences before runtime.

Verification

Rerun the failing path and confirm it either succeeds or fails with the intended validation message at the correct boundary. A clear boundary failure is preferable to a deep, anonymous NPE. Enabling nullability analysis in the build catches many of these before they ever reach runtime.

Diagnostic commands

Check the behavior with commands like these:

java -XX:+ShowCodeDetailsInExceptionMessages App 2>&1 | head
cat hs_err_pid*.log 2>/dev/null ; App 2>&1 | grep -A2 NullPointer
Objects.requireNonNull(input, "input must not be null")