Fix java.lang.NullPointerException in Java

beginnerโ˜• Java2026-03-17| Java 8+ (JDK/JRE), any OS (Linux, macOS, Windows), Spring Boot, Maven/Gradle projects

Error Message

java.lang.NullPointerException
#java#nullpointerexception#exception

The Error

Exception in thread "main" java.lang.NullPointerException
    at com.example.UserService.getUsername(UserService.java:42)
    at com.example.Main.main(Main.java:15)

In Spring Boot you might see the more descriptive form added in Java 14:

java.lang.NullPointerException: Cannot invoke "com.example.User.getName()" because "user" is null

NPE is the most common Java runtime exception โ€” it shows up in virtually every production codebase. The JVM throws it when you try to use a reference that points to nothing: calling a method, accessing a field, or indexing an array on a null object.

Why It Happens

Your stack trace has the answer. Look at it before anything else. The root cause almost always falls into one of these buckets:

  • A method returned null and you used the result without checking
  • A field was never initialized (forgot new)
  • An autowired bean is null โ€” Spring context wasn't loaded in tests
  • A collection or array element is null
  • Method chaining on something that can return null

Step-by-Step Fix

Step 1: Read the Stack Trace

Don't skip this. The stack trace gives you the exact file and line number. Find the top-most line that's in your code โ€” not JDK or framework internals:

at com.example.UserService.getUsername(UserService.java:42)

Go to line 42. That's where the null was dereferenced. Figure out which object on that line is null.

Step 2: Add a Null Check (Quick Fix)

Fastest patch โ€” add a guard before using the value:

// Before (crashes if user is null)
String name = user.getName();

// After
if (user != null) {
    String name = user.getName();
} else {
    log.warn("User is null, skipping name lookup");
}

Step 3: Use Optional (Cleaner Fix)

Java 8's Optional makes null handling explicit and chainable. Use it when a method might legitimately return no result:

// Return Optional instead of null
public Optional<User> findUser(Long id) {
    User user = dao.find(id); // returns null if not found
    return Optional.ofNullable(user);
}

// At the call site โ€” no null check needed
String name = findUser(userId)
    .map(User::getName)
    .orElse("Unknown");

Step 4: Fix Uninitialized Fields

NPE on a field access usually means the field was never assigned. Initialize it at declaration:

// Broken โ€” list is never initialized
public class OrderService {
    private List<Order> orders;

    public void addOrder(Order o) {
        orders.add(o); // NPE here
    }
}

// Fixed
public class OrderService {
    private List<Order> orders = new ArrayList<>();

    public void addOrder(Order o) {
        orders.add(o); // works
    }
}

Step 5: Fix Spring Autowiring NPE

Classic Spring mistake โ€” you instantiated the class yourself with new instead of letting Spring manage it:

// Broken โ€” Spring never sees this instance, repo is null inside
UserService service = new UserService();
service.doSomething(); // NPE inside

// Fixed โ€” let Spring inject it
@Autowired
private UserService service;

In unit tests where the Spring context isn't loaded, mock your dependencies with Mockito instead:

@ExtendWith(MockitoExtension.class)
class UserServiceTest {
    @Mock
    private UserRepository repo;

    @InjectMocks
    private UserService service;

    @Test
    void testGetUser() {
        when(repo.findById(1L)).thenReturn(new User("Alice"));
        assertEquals("Alice", service.getUsername(1L));
    }
}

Step 6: Fix Method Chaining NPE

A chain like a.getB().getC().getValue() will NPE if any step returns null. Wrap it with Optional:

// Risky โ€” any link in this chain can be null
String city = order.getCustomer().getAddress().getCity();

// Safe with Optional
String city = Optional.ofNullable(order)
    .map(Order::getCustomer)
    .map(Customer::getAddress)
    .map(Address::getCity)
    .orElse("N/A");

Step 7: Enable Helpful NPE Messages (Java 14+)

Starting with Java 14, the JVM can tell you exactly which part of an expression was null โ€” not just the line number. It's on by default from Java 15 onward:

# Enable explicitly on Java 14
java -XX:+ShowCodeDetailsInExceptionMessages YourApp

# Error output becomes much more specific:
# Cannot invoke "Address.getCity()" because the return value
# of "Customer.getAddress()" is null

On Java 8โ€“13, add structured logging around the suspect chain to narrow it down manually.

Verify the Fix

  • Re-run the code path that triggered the NPE โ€” confirm it no longer throws
  • Write a unit test that covers the null case explicitly:
@Test
void shouldHandleNullUser() {
    when(repo.findById(99L)).thenReturn(null);
    String result = service.getUsername(99L);
    assertEquals("Unknown", result); // returns default, not an exception
}
  • Check your logs โ€” if you added a log.warn on the null path, verify it appears without crashing downstream

Quick Reference: Common Patterns

// Objects.requireNonNull โ€” fail fast with a clear message
public UserService(UserRepository repo) {
    this.repo = Objects.requireNonNull(repo, "repo must not be null");
}

// Return empty collection instead of null
public List<User> getUsers() {
    List<User> result = repo.findAll();
    return result != null ? result : Collections.emptyList();
}

// String comparison โ€” put the constant on the left
if ("ACTIVE".equals(status)) { ... } // safe even if status is null

Debugging Tips

  • Set a breakpoint at the NPE line and inspect variables in your IDE โ€” you'll see the null reference immediately
  • NPE only in production? Add a temporary log line before the crash to print the suspect variable, then redeploy
  • IntelliJ IDEA highlights NPE-prone code using @NotNull / @Nullable annotations โ€” enable it under Settings โ†’ Editor โ†’ Inspections โ†’ Java โ†’ Probable bugs
  • For compile-time null safety, try Lombok's @NonNull or the Checker Framework's nullness checker

Related Error Notes