< prev index next >

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

Print this page
rev 59936 : 8248476: No helpful NullPointerException message after calling fillInStackTrace
Summary: reported by christoph.dreis@freenet.de
Reviewed-by:


  53     @java.io.Serial
  54     private static final long serialVersionUID = 5162710183389028792L;
  55 
  56     /**
  57      * Constructs a {@code NullPointerException} with no detail message.
  58      */
  59     public NullPointerException() {
  60         super();
  61     }
  62 
  63     /**
  64      * Constructs a {@code NullPointerException} with the specified
  65      * detail message.
  66      *
  67      * @param   s   the detail message.
  68      */
  69     public NullPointerException(String s) {
  70         super(s);
  71     }
  72 























  73     /**
  74      * Returns the detail message string of this throwable.
  75      *
  76      * <p> If a non-null message was supplied in a constructor it is
  77      * returned. Otherwise, an implementation specific message or
  78      * {@code null} is returned.
  79      *
  80      * @implNote
  81      * If no explicit message was passed to the constructor, and as
  82      * long as certain internal information is available, a verbose
  83      * description of the null reference is returned.
  84      * The internal information is not available in deserialized
  85      * NullPointerExceptions.
  86      *
  87      * @return the detail message string, which may be {@code null}.
  88      */
  89     public String getMessage() {
  90         String message = super.getMessage();
  91         if (message == null) {
  92             return getExtendedNPEMessage();









  93         }
  94         return message;
  95     }
  96 
  97     /**
  98      * Get an extended exception message. This returns a string describing
  99      * the location and cause of the exception. It returns null for
 100      * exceptions where this is not applicable.
 101      */
 102     private native String getExtendedNPEMessage();






 103 }


  53     @java.io.Serial
  54     private static final long serialVersionUID = 5162710183389028792L;
  55 
  56     /**
  57      * Constructs a {@code NullPointerException} with no detail message.
  58      */
  59     public NullPointerException() {
  60         super();
  61     }
  62 
  63     /**
  64      * Constructs a {@code NullPointerException} with the specified
  65      * detail message.
  66      *
  67      * @param   s   the detail message.
  68      */
  69     public NullPointerException(String s) {
  70         super(s);
  71     }
  72 
  73     private static final String MUST_COMPUTE_EXTENDED_MESSAGE =
  74         "MUST_COMPUTE_EXTENDED_MESSAGE";
  75     private static final String NO_EXTENDED_MESSAGE =
  76         "NO_EXTENDED_MESSAGE";
  77     private transient String extendedMessage;
  78 
  79     /**
  80      * {@inheritDoc}
  81      */
  82     public synchronized Throwable fillInStackTrace() {
  83         // After the stack trace is changed the extended NPE algorithm
  84         // will compute a wrong message. So compute it beforehand.
  85         if (extendedMessage == null) {
  86             // The first call. Don't compute the message, we'll
  87             // do it lazily.
  88             extendedMessage = MUST_COMPUTE_EXTENDED_MESSAGE;
  89         } else if (extendedMessage == MUST_COMPUTE_EXTENDED_MESSAGE) {
  90             // The second call.
  91             extendedMessage = getExtendedNPEMessage();
  92         }
  93         return super.fillInStackTrace();
  94     }
  95 
  96     /**
  97      * Returns the detail message string of this throwable.
  98      *
  99      * <p> If a non-null message was supplied in a constructor it is
 100      * returned. Otherwise, an implementation specific message or
 101      * {@code null} is returned.
 102      *
 103      * @implNote
 104      * If no explicit message was passed to the constructor, and as
 105      * long as certain internal information is available, a verbose
 106      * description of the null reference is returned.
 107      * The internal information is not available in deserialized
 108      * NullPointerExceptions.
 109      *
 110      * @return the detail message string, which may be {@code null}.
 111      */
 112     public String getMessage() {
 113         String message = super.getMessage();
 114         if (message == null) {
 115             synchronized(this) {
 116                 if (extendedMessage == MUST_COMPUTE_EXTENDED_MESSAGE) {
 117                     // Only the original stack trace was filled in. Message will
 118                     // compute correctly.
 119                     extendedMessage = getExtendedNPEMessage();
 120                 }
 121                 if (extendedMessage != NO_EXTENDED_MESSAGE) {
 122                     return extendedMessage;
 123                 }
 124             }
 125         }
 126         return message;
 127     }
 128 
 129     /**
 130      * Get an extended exception message. This returns a string describing
 131      * the location and cause of the exception. It returns NO_EXTENDED_MESSAGE for
 132      * exceptions where this is not applicable.
 133      */
 134     private String getExtendedNPEMessage() {
 135         String msg = getExtendedNPEMessage0();
 136         if (msg == null) return NO_EXTENDED_MESSAGE;
 137         return msg;
 138     }
 139 
 140     private native String getExtendedNPEMessage0();
 141 }
< prev index next >