Java Optional — Eliminate NullPointerException From Your Code Forever
NullPointerException is called the “billion-dollar mistake” by the man who invented null references.
Get Dhruval Vaishnav’s stories in your inbox
Join Medium for free to get updates from this writer.
Java 8’s Optional is the cure. Here's how to use it correctly.
The Problem
public String getUserCity(Long userId) {
User user = userRepository.findById(userId); // might be null
return user.getAddress().getCity(); // NullPointerException waiting to happen!
}You need 3 null checks. Forget one — your app crashes in production.
What is Optional?
Optional<T> is a container that either contains a value or is empty. It forces you to handle the "no value" case explicitly.
Optional<User> user = userRepository.findById(userId);
// This is EXPLICIT - you KNOW it might be emptyCreating Optionals
Optional<String> present = Optional.of("hello"); // has value
Optional<String> empty = Optional.empty(); // no value
Optional<String> nullable = Optional.ofNullable(getName()); // might be nullThe Right Way to Use Optional
Optional<User> optUser = userRepository.findById(userId);
// ✅ orElseThrow - most common in Spring Boot
User user = optUser.orElseThrow(() ->
new UserNotFoundException("User not found: " + userId));
// ✅ orElse - provide a default
String name = optUser.map(User::getName).orElse("Anonymous");
// ✅ orElseGet - lazy default (only computed if empty)
User defaultUser = optUser.orElseGet(() -> userService.getGuestUser());
// ✅ ifPresent - do something only if present
optUser.ifPresent(u -> emailService.sendWelcome(u.getEmail()));
// ✅ map + filter - transform safely
Optional<String> city = optUser
.map(User::getAddress)
.map(Address::getCity)
.filter(c -> !c.isEmpty());What NOT to Do With Optional
// ❌ WRONG — defeats the purpose
if (optUser.isPresent()) {
User user = optUser.get(); // just like null check!
}
// ❌ WRONG — Optional as method parameter
public void processUser(Optional<User> user) { ... } // use overloading instead
// ❌ WRONG — Optional in entity fields
@Entity
public class User {
private Optional<String> middleName; // not serializable!
}
// ❌ WRONG — Optional.get() without check
User user = optUser.get(); // throws NoSuchElementException if empty!Real Spring Boot Usage
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email); // Spring Data returns Optional
}
@Service
public class AuthService {
public User authenticate(String email, String password) {
return userRepository.findByEmail(email)
.filter(u -> passwordEncoder.matches(password, u.getPassword()))
.orElseThrow(() -> new UnauthorizedException("Invalid credentials"));
}
}Clean. No null checks. Readable. ✅
🎯 Interview Tips
Q: When should you use Optional?
As return types for methods that might not return a value.
Never as method parameters, constructor arguments, or entity fields.
Q: What’s the difference between orElse and orElseGet?
orElsealways evaluates the default value even if Optional is present.orElseGetuses a supplier — only called if empty. UseorElseGetfor expensive defaults.
Follow me for daily Java content. 🚀
#Java #Optional #Java8 #NullPointerException #Backend







