Varargs, Returns, and Documentation
Source: Effective Java, 3rd Edition — Chapter 8 by Joshua Bloch (Items 53–56)
This lesson closes Chapter 8: varargs, returning empty containers and optionals, and Javadoc for exported APIs.
Item 53: Use varargs judiciously
Varargs (int... args) build an array at each call site. Fine for printf, reflection, and variable-arity utilities like sum(int... args).
Wrong for “one or more” arguments:
static int min(int... args) { if (args.length == 0) throw ... } // fails at runtime if empty
Right: require at least one ordinary parameter, then varargs for the rest:
static int min(int firstArg, int... remainingArgs) { ... }
Every varargs call allocates an array — in hot paths, overload foo(), foo(int), … foo(int,int,int,int...) like EnumSet factories (Item 36). Do not overload varargs methods except as in Item 52.
Item 54: Return empty collections or arrays, not nulls
Returning null for “no results” forces every caller to null-check — easy to forget, and errors surface far from the bug.
// Don't
return cheesesInStock.isEmpty() ? null : new ArrayList<>(cheesesInStock);
// Do
return new ArrayList<>(cheesesInStock);
If profiling shows empty allocations matter, reuse Collections.emptyList() / emptySet() / emptyMap() (immutable, shareable). For arrays: toArray(new Cheese[0]), or a shared EMPTY_ARRAY. Do not preallocate toArray(new T[size]) for performance (counterproductive).
Empty collections
1 / 2getCheeses returns null when the shop has no cheese
Pick an answer to see if you are right.
Item 55: Return optionals judiciously
Optional<T> (Java 8) models “maybe a value” without null returns or exceptions for ordinary absence. Use when a method may have no result and callers must explicitly handle that case.
public static <E extends Comparable<E>> Optional<E> max(Collection<E> c) {
if (c.isEmpty()) return Optional.empty();
...
return Optional.of(result);
}
Never return null from an Optional-returning method. Clients use orElse, orElseThrow, orElseGet, map, flatMap. For primitives use OptionalInt etc., not Optional<Integer>.
Do not wrap collections/maps in optionals (return empty container, Item 54). Optionals are primarily return types, not fields/map values (exceptions like optional getters on rich DTOs exist).
Item 56: Write doc comments for all exposed API elements
Document every exported class, interface, constructor, method, and field with Javadoc (/** ... */). Describe the contract (what, not how): preconditions, postconditions, side effects.
Include for methods:
@paramfor each parameter@returnunlessvoid(unless redundant by your style guide)@throwsfor every thrown exception (ifclause after the tag)
Use {@code ...} for inline code, {@literal ...} for HTML metacharacters, {@implSpec} for inheritance self-use (Item 19). Summary sentence: verb phrase for methods, noun phrase for types/fields. Document enum constants, generic @param <T>, and annotation members.
Javadoc
1 / 2Exported method with no doc comment
Pick an answer to see if you are right.
Items 53–56 map
| Item | Move |
|---|---|
| 53 | Varargs for 0+; required param + varargs for 1+ |
| 54 | Empty collections/arrays, not null |
| 55 | Optional for absent results; not for containers |
| 56 | Javadoc every exported API; @param @return @throws |
Chapter 8 complete. Next: Scope, Loops, and Types (Chapter 9, Items 57–62).