Best practice to validate null and empty collection in Java
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The best practice in Java is usually to avoid null collections altogether and use empty collections to represent "no items." When you cannot guarantee that, the next best approach is to centralize the null and emptiness check in simple, readable code rather than scattering inconsistent checks across the codebase.
Prefer Empty Collections Over null
If you control the API, return an empty collection instead of null. That removes an entire class of defensive checks from calling code.
Now callers can safely use isEmpty, iterate, or stream the result without checking for null first.
Use the Plain Java Check When Needed
If null is still possible, the standard check is short and perfectly acceptable.
This is usually all you need. It is clear, fast, and has no external dependency cost.
Validate at the Boundary, Not Everywhere
The cleanest place to normalize null or reject it is at a boundary:
- request mapping layer
- repository adapter
- constructor
- setter or factory method
Once the data is normalized, the rest of the system can work with normal collections instead of mixed null and empty semantics.
That keeps the null-handling rule in one place instead of repeating it in every consumer.
Be Careful with Utility Libraries
Libraries such as Apache Commons Collections provide helpers like CollectionUtils.isEmpty(collection). Those are convenient if the dependency is already present, but they are not necessary for something this small.
The key question is consistency, not cleverness. A simple in-house utility or direct Java check is usually enough.
Avoid Overusing Optional for Collections
An Optional<List<T>> is often a smell because the collection itself already has an "empty" state. Most of the time, List<T> with an empty list is simpler than mixing Optional and collection semantics together.
This is generally easier to consume than Optional<List<String>>.
Make the Semantic Meaning Explicit
Sometimes null and empty do mean different things. For example:
- '
nullmight mean "value not provided"' - empty might mean "provided, but intentionally contains no items"
If that distinction matters, encode it explicitly in the API or surrounding model instead of letting callers guess. The correct best practice depends on the business meaning, not on style alone.
Prefer One Shared Helper If the Pattern Repeats
If your codebase checks collections constantly, create one tiny helper and standardize on it. That keeps the intent obvious and avoids half a dozen slightly different versions of the same validation rule.
Common Pitfalls
- Returning
nullcollections from APIs when an empty collection would work better. - Repeating
collection != null && !collection.isEmpty()everywhere instead of normalizing earlier. - Introducing
Optional<Collection<T>>where a plain collection would be clearer. - Using a library helper for trivial checks without any consistency benefit.
- Ignoring cases where
nulland empty actually have different business meanings.
Summary
- Prefer empty collections over
nullwhenever you control the API. - When
nullis possible,collection == null || collection.isEmpty()is a good default check. - Normalize or validate collections at system boundaries to reduce repeated checks.
- Avoid
Optional<Collection<T>>in most cases. - Let business meaning, not habit, determine whether
nulland empty should be treated the same.

