One of the less-appreciated of the many massive improvements made to Java in version 1.5 was varargs, aka those little dots that are syntactic sugar sprinkled onto a strongly-typed array:
public static void printAllOfThese(String... things) { for (String thing : things) { System.out.println(thing); } }
It goes hand-in-glove with the enhanced for loop. Very tidy. Except what happens when I inadvertently do this:?
printAllOfThese(null);
You probably correctly guessed: NullPointerException at line 1 of printAllOfThese - yep - sadly, the enhanced for loop is not null-safe. What we really want is for a null argument to be silently ignored. So our previously oh-so-tidy, oh-so-readable varargs method ends up needing a null-check wart:
public static void printAllOfThese(String... things) { if (things != null) { for (String thing : things) { System.out.println(thing); } } }
Ew. That's ugly, and in turn requires more test cases. There has to be a better way, but amazingly, I couldn't find any solution in the usual common libraries. So, somewhat reluctantly (because if premature optimisation is the root of all evil, then wheel-reinvention is surely sudo), I present the VarargIterator helper class:
public class VarargIterator { /** * @return an {@link Iterable} of a suitable type. * Null-safe; passing a null varargs will simply return * an "empty" {@code Iterable}. */ public static final <T> Iterable<T> forArgs(T... optionalArgs) { if (optionalArgs == null) { return Collections.emptyList(); } else { return Arrays.asList(optionalArgs); } } }
This allows us to rewrite our printAllOfThese method very neatly:
public static void printAllOfThese(String... things) { for (String thing : VarargIterator.forArgs(things)) { System.out.println(thing); } }
Next time: Elegantly dealing with compulsory and optional elements.
No comments:
Post a Comment
Comments welcome - spam is not. Spam will be detected, deleted and the source IP blocked.