/errors/java/nullpointerexception-cannot-invoke-because-is-null
java.lang.NullPointerException: Cannot invoke "String.length()" because "name" is null
- tool
- Java
- exit code
- 1
- versions
- JDK 14+ (helpful messages), On by default since JDK 15
- os
- any
java.lang.NullPointerException: Cannot invoke "String.length()" because "name" is null says exactly what failed: the code called length() on the variable name, and name was null. These helpful NullPointerException messages (JEP 358) exist since JDK 14 and are on by default since JDK 15. Go to the line in the stack trace, find where the named variable was assigned, and handle the null case.
Reproduce it
cat > Npe.java <<'EOF'
public class Npe {
static String findName(int id) { return id == 1 ? "admin" : null; }
public static void main(String[] args) {
String name = findName(2);
System.out.println(name.length());
}
}
EOF
echo "--- compiled with javac -g"
javac -g Npe.java && java Npe
echo "--- run as a source file"
java Npe.javaOutput · exit 1
--- compiled with javac -g Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "name" is null at Npe.main(Npe.java:5) --- run as a source file Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "<local1>" is null at Npe.main(Npe.java:5)
Why it sometimes says <local1>
The variable name comes from the class file's local variable table, which javac writes only with -g. Without it (and in the single-file source launcher, java Npe.java), the JVM can only print the slot number: because "<local1>" is null. Maven and Gradle compile with debug information by default, so application stack traces usually show real names. Fields, method calls and array elements are always named, for example because the return value of "Map.get(Object)" is null.
Fixes
// 1. Check and handle the empty case
String name = findName(id);
int len = (name == null) ? 0 : name.length();
// 2. Default value (Java 9+)
String safe = java.util.Objects.requireNonNullElse(findName(id), "guest");
// 3. Make absence explicit in the API
static java.util.Optional<String> findName(int id) { ... }
int len2 = findName(id).map(String::length).orElse(0);
// 4. Fail early with a clear message where null is a bug
this.name = java.util.Objects.requireNonNull(name, "name must not be null");