본문 바로가기
effective java

Item 53. 가변인수는 신중히 사용하라

by mjjang 2022. 3. 6.

가변인수 메서드는 명시한 타입의 인수를 0개 이상 받을 수 있습니다.

private static int sum(int... args) {
    int[] arg = new int[3];

    int sum = 0;
    for (int arg : args) {
        sum += arg;
    }
    return sum;
}

sum(1, 2, 3)은 6을 리턴, sum()은 0을 리턴합니다.

최솟값을 찾는 메서드는 인수가 최소 1개 이상이어야 할 수 있습니다.

private static int min(int... args) {
    if (args.length == 0) {
        throw new IllegalArgumentException("인수가 1개 이상 필요합니다.");
    }
    int min = args[0];
    for (int arg : args) {
        if (arg < min) {
            min = arg;
        }
    }
    return min;
}

위 코드는 몇 가지 문제점이 있습니다. 먼저 인수를 0개만 넣어서 호출하면 컴파일 타임이 아닌 런타임에 실패합니다. 그리고 코드도 깔끔하지 못합니다. 이럴 때는 매개 변수를 2개 받아 깔끔한 코드를 만들 수 있습니다.

private static int min(int firstArg, int... args) {
    int min = firstArg;
    for (int arg : args) {
        min = Math.min(min, arg);
    }
    return min;
}

첫 번째로 평범한 매개변수를 받고, 가변인수를 두 번째로 받으면 됩니다.

성능에 민감한 경우

가변 인수 메서드는 호출될 때마다 배열을 새로 하나 할당하고 초기화 합니다. 이럴 경우 성능을 개선할 수 있는 패턴이 있습니다.

public void foo() { }
public void foo(int a1) { }
public void foo(int a1, int a2) { }
public void foo(int a1, int a2, int a3) { }
public void foo(int a1, int a2, int a3, int... rest) { }

예를 들어 해당 메서드 호출의 대부분이 인수가 0 ~ 3개일 경우에는 위와 같이 다중 정의한다면

대부분의 메소드는 가변 인수를 사용하지 않게 되고 4개 이상일 경우(극히 드문)에만 가변 인수를 사용하기 때문에 성능 문제가 해결된다. EunmSet의 정적 팩토리도 이 패턴을 사용합니다.

핵심 정리

  • 인수 개수가 일정하지 않은 메서드를 정의해야 한다면 가변 인수가 반드시 필요하다.
  • 메서드를 정의할 때 필수 매개변수는 가변 인수 앞에 두자.
  • 성능 문제까지 고려하자.

댓글