가변인수는 신중히 사용하라
static int sum(int ... args) {
//...
}
가변인수 메서드를 호출하면, 가장 먼저 인수의 개수와 길이가 같은 배열을 만들고 인수들을 이 배열에 저장해 가변인수 메서드에 건네준다.
static int min(int firstNumber, int... numbers) {
int min = firstNumber;
for (int number : numers) {
if (number < min) {
min = number;
}
}
return min;
}
2개를 받도록 해서 하나는 무조건 보장한다면 0개가 들어오는 경우(유효성 검사 필요없어짐)에 대해 막을 수 있다.
성능에 민감한 상황이라면 가변인수가 걸림돌이 될 수 있다. 가변인수 메서드는 호출될 때마다 배열을 새로 하나 할당하고 초기화한다.
public void foo(int number1)
public void foo(int number1, int number2)
public void foo(int number1, int nubmer2, int number3)
public void foo(int number1, int nubmer2, int number3, int... numbers)
만약 95%가 인자 3개 이하라면 미리 만들고, 나머지 5%가 다중정의 메서드를 호출하도록 하는 패턴을 사용해 성능으로 이점을 볼 수 있다.
EnumSet의 정적 팩터리도 이 패턴을 사용한다.
public static <E extends Enum<E>> EnumSet<E> of(E e) {
EnumSet<E> result = noneOf(e.getDeclaringClass());
result.add(e);
return result;
}
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2) {
EnumSet<E> result = noneOf(e1.getDeclaringClass());
result.add(e1);
result.add(e2);
return result;
}
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3) {
EnumSet<E> result = noneOf(e1.getDeclaringClass());
result.add(e1);
result.add(e2);
result.add(e3);
return result;
}
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4) {
EnumSet<E> result = noneOf(e1.getDeclaringClass());
result.add(e1);
result.add(e2);
result.add(e3);
result.add(e4);
return result;
}
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4,
E e5) {
EnumSet<E> result = noneOf(e1.getDeclaringClass());
result.add(e1);
result.add(e2);
result.add(e3);
result.add(e4);
result.add(e5);
return result;
}
@SafeVarargs
public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {
EnumSet<E> result = noneOf(first.getDeclaringClass());
result.add(first);
for (E e : rest)
result.add(e);
return result;
}