skip to content

How do you enable Helpful NullPointerExceptions, and in which Java versions are they available or on by default?

level: middleimportance: should knowfreq 48%

answer

  1. Flag: -XX:+ShowCodeDetailsInExceptionMessages
  2. Java 14 = opt-in
  3. Java 15+ = default on
  4. '+' enables, '-' disables in -XX syntax
  5. Set at JVM start (cmd line / JAVA_TOOL_OPTIONS / run config)

basics

~10 s

They arrived in Java 14, where you turn them on with the JVM flag -XX:+ShowCodeDetailsInExceptionMessages. From Java 15 onward they are on by default.

solid answer

~40 s

Helpful NullPointerExceptions shipped in Java 14 under JEP 358, but they were off by default there — you opted in by passing -XX:+ShowCodeDetailsInExceptionMessages to the JVM (for example in JAVA_TOOL_OPTIONS, the command line, or your launch config). Starting with Java 15 the feature became the default, so any modern JDK gives you the detailed messages with no configuration. If you ever need to suppress them — say a message could expose sensitive variable names, or you want to match legacy output — you disable them with -XX:-ShowCodeDetailsInExceptionMessages. The flag controls only the message detail; the exception and its behaviour are identical either way. It applies to NPE messages broadly, not just chained field access.

code

java · 8 lines
java
// Java 14: opt in explicitly
//   java -XX:+ShowCodeDetailsInExceptionMessages -jar app.jar
//
// Java 15+: already on; opt out if you must
//   java -XX:-ShowCodeDetailsInExceptionMessages -jar app.jar
//
// Or for any JVM launch:
//   export JAVA_TOOL_OPTIONS="-XX:+ShowCodeDetailsInExceptionMessages"

go deeper

for a junior

Knows modern Java gives detailed NPE messages out of the box and roughly that it started around Java 14/15.

for a middle

States the exact flag, that Java 14 is opt-in and Java 15+ is default, and where to set JVM args.

for a senior

Adds the +/- semantics, that detail is computed lazily with no happy-path cost, and the disable rationale (name leakage).

for a principal

Discusses rollout/version policy across a fleet, the security/log-hygiene trade-off, and ensuring messages aren't surfaced to untrusted users regardless of the flag.

## The feature and its flag **Helpful NullPointerExceptions** (JEP 358) make the JVM attach a precise, source-level description to a `NullPointerException` — naming the null sub-expression and the operation that failed. The behaviour is gated by a single **HotSpot diagnostic flag**: ``` -XX:+ShowCodeDetailsInExceptionMessages # enable (the '+' turns it ON) -XX:-ShowCodeDetailsInExceptionMessages # disable (the '-' turns it OFF) ``` In HotSpot's `-XX` flag syntax, `+` means *on* and `-` means *off*. ## Version timeline - **Java 14:** feature introduced, but **off by default**. You must pass `-XX:+ShowCodeDetailsInExceptionMessages` to see the detailed messages. - **Java 15 and later:** **on by default**. Nothing to configure; the rich message appears automatically. You can still opt *out* with the `-` form. ## Where to set the flag It is a normal JVM startup argument, so you can supply it wherever JVM args go: - On the command line: `java -XX:+ShowCodeDetailsInExceptionMessages -jar app.jar` - Via the `JAVA_TOOL_OPTIONS` environment variable (picked up by any JVM launch). - In a build/run tool's JVM-args setting (Gradle `application` runtime args, Maven Surefire `argLine`, an IDE run configuration). Because it must be known at JVM start, you cannot toggle it at runtime from inside the program. ## Why you'd disable it The detailed message can include **variable and field names** from your code. In rare hardening scenarios — exception messages surfaced to untrusted users, or strict log-hygiene rules — you might prefer the terse message and disable the flag. In almost all development and most production settings, leaving it on is the right call because the diagnostic value is large and the risk is small (messages should not be shown to end users anyway). ## What it does and does not affect The flag changes **only the text** of the NPE message. It does not alter which exceptions are thrown, performance of normal code paths, or `catch` behaviour. The detail is computed **lazily**, only when an NPE is actually constructed, so there is no cost on the happy path.

  • Can you turn the feature on or off while the program is already running?
    No — it is a JVM startup flag, so it must be set before the JVM launches; it cannot be toggled at runtime from application code.
  • Why might someone deliberately disable it in production?
    The detailed message can leak internal variable/field names. If exception messages might reach untrusted consumers or violate log-hygiene policy, disabling it (or never exposing messages) reduces that surface.

saying these in an interview costs you the question

  • Saying it is on by default in Java 14 — it is off there and only default from Java 15.
  • Thinking '+'/'-' are typos — in -XX syntax they explicitly mean enable/disable.
  • Believing you can flip it at runtime via a system property or method call.

context