< prev index next >

src/java.base/share/classes/java/lang/NullPointerException.java

Print this page
rev 53693 : wq8218628: Add detailed message to NullPointerException describing what is null.

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -23,10 +23,12 @@
  * questions.
  */
 
 package java.lang;
 
+import java.lang.reflect.Field;
+
 /**
  * Thrown when an application attempts to use {@code null} in a
  * case where an object is required. These include:
  * <ul>
  * <li>Calling the instance method of a {@code null} object.

@@ -51,15 +53,24 @@
  */
 public
 class NullPointerException extends RuntimeException {
     private static final long serialVersionUID = 5162710183389028792L;
 
+    /*
+     * If set a message describing the exception is computed when first calling
+     * getMessage(). A precise description of the location in the code and
+     * the entitiy being null will be computed. This message is stored in
+     * detailMessage and this flag is set to false.
+     */
+    private transient boolean lazyComputeMessage;
+
     /**
      * Constructs a {@code NullPointerException} with no detail message.
      */
     public NullPointerException() {
         super();
+        lazyComputeMessage = true;
     }
 
     /**
      * Constructs a {@code NullPointerException} with the specified
      * detail message.

@@ -67,6 +78,45 @@
      * @param   s   the detail message.
      */
     public NullPointerException(String s) {
         super(s);
     }
+    
+    /**
+     * Returns the detail message string of this throwable.
+     *
+     * @return  the detail message string of this {@code Throwable} instance
+     *          (which may be {@code null}).
+     */
+    public String getMessage() {
+        synchronized (this) {
+            if (!lazyComputeMessage) {
+                return super.getMessage();
+            }
+        }
+
+        String extendedMessage = getExtendedNPEMessage(super.getMessage());
+        
+        if (extendedMessage != null) {
+            synchronized (this) {
+                if (lazyComputeMessage) {
+                    setMessage(extendedMessage);
+                    lazyComputeMessage = false;
+                }
+            }
+        }
+
+        return extendedMessage;
+    }
+
+    // Install the extendedMessage in the Throwable.defaultMessage before
+    // serializing.
+    private Object writeReplace() {
+        getMessage();
+        return this;
+    }
+
+    // Get an extended exception message. This adds a string describing
+    // the location and cause of the exception. It returns defaultMessage
+    // for exceptions where this is not applicable.
+    private native String getExtendedNPEMessage(String defaultMessage);
 }
< prev index next >