Apex's null semantics are mostly Java-like, with some Salesforce-specific quirks.
What is null:
- Variables declared but uninitialised:
String s;isnull. - sObject fields not selected in SOQL come back as null — even if they have values in the DB.
- Empty collections are NOT null —
new List<Account>()is empty but non-null. nullreturns true for==against anothernull.
NullPointerException sources:
- Calling a method on
null:acc.Name.toLowerCase()whenaccoracc.Nameis null. - Dereferencing a map's value when key not present:
myMap.get(badKey).field—get()returns null, then dereferencing fails. - SOQL returning empty list, then
.get(0)on it — IndexOutOfBoundsException, not NPE, but similar pattern.
Patterns to avoid NPEs:
- Safe navigation operator (Apex equivalent:
?.):
apex String name = acc?.Account?.Name;
- Null check before access:
apex if (acc != null && acc.Name != null) { ... }
- Default values via `.get(key, defaultValue)` — Map's get with default.
- String.isBlank() / String.isEmpty() — check string-ness without NPE.
- `List.isEmpty()` before accessing element by index.
- Null-coalescing for primitives:
apex Decimal amount = opp.Amount == null ? 0 : opp.Amount;
The single biggest source of NPEs in Apex is querying with LIMIT 1 and then accessing the result without checking if the list is empty.
