Check two arguments in Java, either both not null or both null elegantly
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Sometimes two Java arguments are valid only as a pair. Coordinates, date ranges, and optional credentials often follow the same rule: either both values are present or both are absent. The cleanest code expresses that rule directly instead of burying it inside a long boolean expression.
The Shortest Correct Check
If the invalid case is "exactly one value is null", the direct condition is:
This works because (left == null) and (right == null) are booleans. The != operator is true only when those boolean values differ, which is exactly the mixed null-state case you want to reject.
That makes it more compact than the longer equivalent:
Both versions are correct. The first one is usually easier to read once you know what it means.
Turn the Rule Into a Reusable Helper
If the pattern appears in several constructors or service methods, extract it into a utility:
Usage:
This keeps domain code focused on the actual concept instead of repeating low-level validation logic.
Do Not Confuse Null-State with Equality
Objects.equals(a, b) answers a different question. It checks whether two values are equal, not whether they share the same null-state.
Example:
The pair is valid under the "both present or both absent" rule even though the values are not equal. That is why using equality APIs here often muddies the intent.
Sometimes the Better Fix Is an API Change
Repeatedly validating two nullable parameters is often a design smell. If the values conceptually belong together, wrap them in a single value object:
Now the caller either passes a complete Coordinates object or nothing at all. That avoids the possibility of partial state entirely.
This is often better than passing two boxed types such as Double latitude, Double longitude through multiple layers of code and validating them everywhere.
When a Boolean Is Better Than an Exception
Sometimes you want a predicate instead of a throwing precondition:
This works well in validation frameworks where you want to gather several problems and return them together instead of failing on the first mismatch.
Choosing the Most Readable Form
There are two common readable forms:
- invalid case check:
(a == null) != (b == null) - valid case check:
(a == null) == (b == null)
Pick the one that matches the control flow. If you want to throw on invalid input, the != form is natural. If you want a reusable boolean predicate that returns true for valid pairs, the == form reads better.
Common Pitfalls
One common mistake is using Objects.equals(a, b) and assuming that covers the null-pair rule. It does not. Equality and null-state are different concepts.
Another mistake is writing the condition in a much longer form than necessary. Validation logic should be easy to scan because it often sits at the edge of important API boundaries.
Developers also sometimes reach for Optional as a parameter type just to express this rule. In most Java code, that makes call sites noisier without improving clarity.
Finally, if the same pair check appears repeatedly, take that as a hint that a dedicated value object may express the domain more cleanly.
Summary
- Use
(a == null) != (b == null)to detect the invalid mixed case. - Use
(a == null) == (b == null)when you want a boolean predicate for the valid case. - Do not confuse value equality with matching null-state.
- Extract the rule into a helper if it appears often.
- Prefer a value object when the two values conceptually belong together.

