Appearance
NullPointerException
Among all RuntimeException
exceptions, the one most familiar to Java programmers is probably NullPointerException
.
NullPointerException
is a null pointer exception, commonly known as NPE. If an object is null
, calling its methods or accessing its fields will generate NullPointerException
. This exception is usually thrown by the JVM, for example:
java
// NullPointerException
public class Main {
public static void main(String[] args) {
String s = null;
System.out.println(s.toLowerCase());
}
}
The concept of pointers actually comes from the C language, and there are no pointers in the Java language. The variables we define are actually references. Null Pointer is more precisely Null Reference, but there is not much difference between the two.
Handling NullPointerException
If we encounter NullPointerException
, how should we handle it?
First of all, it must be clear NullPointerException
is a code logic error. When encountering NullPointerException
, the principle is to expose it early and fix it early. It is strictly forbidden to use catch
to hide this coding error:
java
// Error example: Catching NullPointerException
try {
transferMoney(from, to, amount);
} catch (NullPointerException e) {
}
Good coding habits can greatly reduce the occurrence of NullPointerException
, for example:
Member variables are initialized when defined:
java
public class Person {
private String name = "";
}
Using the empty string ""
instead of the default null can avoid many NullPointerException
. When writing business logic, using the empty string ""
to indicate that it is not filled in is much safer than null
.
Returns the empty string ""
, an empty array instead of null
:
java
public String[] readLinesFromFile(String file) {
if (getFileSize(file) == 0) {
// Return empty array instead of null:
return new String[0];
}
...
}
This eliminates the need for the caller to check whether the result is null
.
If the caller must judge based on null
, for example, returning null
means the file does not exist, then consider returning Optional<T>
:
java
public Optional<String> readFromFile(String file) {
if (!fileExist(file)) {
return Optional.empty();
}
...
}
In this way, the caller must determine whether there is a result through Optional.isPresent()
.
Locating NullPointerException
If a NullPointerException occurs, for example, when calling a.b.c.x()
, the possible reasons are:
a
isnull
;ab
isnull
;abc
isnull
;
To determine which object is null
you could only print logs like this:
java
System.out.println(a);
System.out.println(a.b);
System.out.println(a.b.c);
Starting from Java 14, if NullPointerException
occurs, the JVM can give detailed information to tell us who the null
object is. Let's look at an example:
java
public class Main {
public static void main(String[] args) {
Person p = new Person();
System.out.println(p.address.city.toLowerCase());
}
}
class Person {
String[] name = new String[2];
Address address = new Address();
}
class Address {
String city;
String street;
String zipcode;
}
You can see something like this in the details of NullPointerException
... because "<local1>.address.city" is null
, meaning that the city
field is null
, so that we can quickly locate the problem.
This enhanced NullPointerException
details is a new feature of Java 14, but it is turned off by default. We can add one to the JVM -XX:+ShowCodeDetailsInExceptionMessages
Parameters to enable it:
sh
java -XX:+ShowCodeDetailsInExceptionMessages Main.java
Summary
NullPointerException
is a common logical error in Java code and should be exposed and repaired early;
You can enable Java 14's enhanced exception information to view detailed error information for NullPointerException
.