💡 필수 매개변수는 가변인수 앞에 두고, 가변인수를 사용할 때는 성능 문제까지 고려하자
📌 가변인수(varargs)
static int sum(int... args) {
int sum = 0;
for (int arg : args)
sum += arg;
return sum;
}
- 가변인수 메서드는 명시한 타입의 인수를 0개 이상 받을 수 있다.
- 가변인수 메서드 호출 시, 가장 먼저 인수의 개수와 길이가 같은 배열을 만들고 인수들을 배열에 저장한다.
- 인수 개수는 런타임에 자동 생성된 배열의 길이 args.length로 알 수 있다.
📌 As-is
// 최솟값을 찾는 메서드
static int min(int... args) {
if (args.length == 0)
throw new IllegalArgumentException("인수가 1개 이상 필요합니다.");
int min = args[0];
for (int i = 1; i < args.length; i++)
if (args[i] < min)
min = args[i];
return min;
}
- 인수를 0개만 넣고 호출하면 (컴파일이 아닌)런타임에 실패한다.
- args 유효성 검사를 명시적으로 해야하고, 코드도 지저분하다.
- min 초기값을 Integer.MAX_VALUE로 설정하지 않고는 더 명료한 for-each문 사용도 불가능하다.
📌 To-be
static int min(int firstArg, int... remainingArgs) {
int min = firstArg;
for (int arg : remainingArgs)
if (arg < min)
min = arg;
return min;
}
- 매개변수를 2개 받도록 하면 해결할 수 있다.
- 가변인수는 인수 개수가 정해지지 않았을 때 아주 유용하다.
📌 주의 사항
public void bar() {}
public void bar(int x) {}
public void bar(int x, int y) {}
public void bar(int x, int y, int z) {}
public void bar(int x, int y, int z, int... args) {}
- 성능에 민감한 상황이면 사용을 지양하라.
- 가변인수 메서드는 호출될 때마다 배열을 새로 하나 할당하고 초기화한다.
- 메서드 호출의 95%가 인수를 3개 이하로 사용한다면, 위와 같은 패턴으로 유연성을 증가시킬 수는 있다.
- EnumSet의 정적 팩터리도 이 기법을 사용해 열거 타입 집합 생성 비용을 최소화한다.