Javaの可変長引数の罠
なんだかくだらないし、罠というほどでもないけれど、多少何か考えさせられる例:
public class UnexpectedVLA { public static void main(final String[] ignored){ // バグを呼ばない. System.out.println(getLowest(3, 1, 5, -3, 4)); // バグを呼ぶ. final Integer[] args = {3, 1, 5, -3, 4}; System.out.println(getLowest(args)); System.out.println(args[0]); // これは3がプリントされず, -3がプリントされる. } // このメソッドはバグがある. private static <T extends Comparable<? super T>> T getLowest(final T... args){ java.util.Arrays.sort(args); return args[0]; } }
この例は「最小の値をとるのにsortを使っている。非常に効率が悪いからバグみたいなもんだ。」ということを示しているのではなく、「#getLowestメソッドに思わぬ副作用がある」ということを示している。
誰もgetLowestを呼び出して副作用があるとは思わないだろう。
この例から分かることは、要するに、可変長引数の配列に一切の副作用を与えてはならない、ということだ。配列をそのままいじりたいならコピーしてから使うべき。
副作用を与えても別にコンパイラから天罰はくだらないが、メソッドインタフェースとしては黒魔術の方向に走っているというのは間違いない。