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を呼び出して副作用があるとは思わないだろう。

この例から分かることは、要するに、可変長引数の配列に一切の副作用を与えてはならない、ということだ。配列をそのままいじりたいならコピーしてから使うべき。

副作用を与えても別にコンパイラから天罰はくだらないが、メソッドインタフェースとしては黒魔術の方向に走っているというのは間違いない。