Java

Null Handling Strategies

Null is the "billion dollar mistake" according to its inventor, Tony Hoare. This article covers strategies to eliminate null-related bugs: Null Object pattern, Optional, defensive coding, and static analysis tools.

📋 At a Glance

AspectDetails
Patterns CoveredNull Object, Optional, Defensive Coding
Primary BenefitEliminate NullPointerException
Java Version8+ (Optional), all (Null Object)
ToolsNullAway, Checker Framework, SpotBugs

🎯 What You'll Learn

  • Null Object Pattern for default behavior
  • Optional proper usage and anti-patterns
  • Defensive coding with fail-fast validation
  • Static analysis for null safety
  • When null is appropriate (yes, sometimes)

🔬 Deep Dive

Pattern 1: Null Object Pattern

JAVA(39 lines)
Code
Loading syntax highlighter...

Pattern 2: Optional Proper Usage

JAVA(59 lines)
Code
Loading syntax highlighter...

Pattern 3: Defensive Coding

JAVA(31 lines)
Code
Loading syntax highlighter...

Pattern 4: Annotations for Static Analysis

JAVA(20 lines)
Code
Loading syntax highlighter...

Pattern 5: Java 21+ Null in Pattern Matching

JAVA(25 lines)
Code
Loading syntax highlighter...

⚠️ When Null is Appropriate

  1. Uninitialized lazy fields (with proper null checks)
  2. Absent optional data in domain (though Optional often better)
  3. Performance-critical code (Optional has overhead)
  4. Framework contracts (JPA entities, etc.)

🐛 Debug This: The Phantom Null

A developer reports: "We added Optional everywhere but still getting NullPointerException. I thought Optional was supposed to fix this!"

JAVA(19 lines)
Code
Loading syntax highlighter...
Why does Optional fail to prevent NPE here? Find all the mistakes!

✅ Solution:

Three distinct Optional anti-patterns:

  1. .get() without .isPresent() - defeats the purpose of Optional
  2. .orElse(null) - reintroduces null into the codebase
  3. .map() to Optional - null values inside Optional cause issues
Correct approach:
JAVA(20 lines)
Code
Loading syntax highlighter...
The lesson: Optional only helps if used correctly. Never call .get() without checking, never use .orElse(null), and handle nested nulls explicitly.

💻 Exercises

Exercise 1: Eliminate Null Returns

⭐ Difficulty: Easy | ⏱️ Time: 15 minutes

Task: Refactor to eliminate null returns.
JAVA(18 lines)
Code
Loading syntax highlighter...
✅ Solution:
JAVA(10 lines)
Code
Loading syntax highlighter...

Exercise 2: Implement Null Object Pattern

⭐⭐ Difficulty: Medium | ⏱️ Time: 20 minutes

Task: Replace null checks with Null Object.
JAVA(25 lines)
Code
Loading syntax highlighter...
✅ Solution:
JAVA(20 lines)
Code
Loading syntax highlighter...

Exercise 3: Defensive Coding

⭐⭐ Difficulty: Medium | ⏱️ Time: 15 minutes

Task: Add fail-fast null validation.
JAVA(12 lines)
Code
Loading syntax highlighter...
✅ Solution:
JAVA(17 lines)
Code
Loading syntax highlighter...

Exercise 4: Optional Chain Refactoring

⭐⭐⭐ Difficulty: Medium-Hard | ⏱️ Time: 20 minutes

Task: Refactor these null checks to Optional chains.
JAVA(12 lines)
Code
Loading syntax highlighter...
✅ Solution:
JAVA(7 lines)
Code
Loading syntax highlighter...

Exercise 5: Static Analysis Setup

⭐⭐⭐⭐ Difficulty: Hard | ⏱️ Time: 25 minutes

Task: Add null-safety annotations and configure static analysis.
JAVA(6 lines)
Code
Loading syntax highlighter...
✅ Solution:
JAVA(30 lines)
Code
Loading syntax highlighter...

🎤 Senior-Level Interview Questions

Q1: When would you use Null Object vs Optional?

A:
  • Null Object: When "nothing" has default behavior (NullDiscount applies no discount)
  • Optional: When "nothing" means absence (no user found)
  • Null Object is about polymorphic behavior, Optional is about presence/absence

Q2: What are Optional anti-patterns?

A:
  • Calling .get() without .isPresent() check
  • Using .orElse(null) - reintroduces null
  • Using Optional as method parameters
  • Using Optional for class fields (serialization issues)
  • Creating Optional just to call .isPresent()

Q3: How do you handle null in legacy code integration?

A:
  • Wrap at boundary: Optional.ofNullable(legacyMethod())
  • Create adapter classes with null-safe API
  • Add @Nullable annotations for documentation
  • Use defensive Objects.requireNonNull() at entry points

📝 Summary

PatternUse When
Null ObjectNeed default behavior
OptionalReturn values that might be absent
requireNonNullValidate parameters
@Nullable/@NonNullStatic analysis

📅 Review Schedule for This Article

DayTaskTime
Day 1Review Null Object vs Optional decision table5 min
Day 3Redo Exercise 1 (Eliminate Null Returns)15 min
Day 7Answer interview questions without looking10 min
Day 14Redo Debug This (Optional anti-patterns)10 min
Day 30Audit one class in your project for null-safety15 min

Next: [Part 9: Builder & Factory Patterns]