카테고리:

업데이트:

1. 들어가기

Java는 JDK 1.5부터 가변인수를 제공하기 시작했습니다.

가변인수는 명시한 타입의 인수를 유동적으로 여러 개 받을 수 있다는 장점이 있습니다.

먼저, 가변인수를 어떻게 사용하는지 알아보겠습니다.

2. 가변인수 사용법

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

다음은 입력받은 int 인수들의 합을 계산해주는 가변인수 메서드입니다.

sum(1, 2, 3)은 6을, sum()은 0을 반환합니다.

3. 가변인수의 문제점

때론, 인수를 1개 이상이어야 할 때도 있습니다.

예를 들어 주어진 인수 중 최소값을 구하는 메서드인데 인수를 0개도 받을 수 있도록 설계하는 것은 좋지 않습니다.

가변인수를 사용한 최솟값 조회 프로그램은 다음과 같습니다.

  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개 들어온다면 컴파일타임이 아닌 런타임에 실패한다는 점입니다.

심지어 코드도 지저분합니다.

그래서 해당 코드를 컴파일타임에 실패하게 하고 코드도 깔끔하게 만들어보겠습니다.

4. 인수를 제한하는 가변인수

  static int min(int firstArg, int... remainArgs) {
    int min = firstArgs;
    for (int arg : remainArgs)
      if (arg < min)
        min = arg;
        
    return min;
  }

다음 코드처럼 매개변수를 2개 받도록 하면 앞서 발생한 코드의 문제점을 말끔하게 해결할 수 있습니다.

5. 가변인수를 효율적으로 사용하는법

가변인수는 호출될 때마다 배열을 새로 하나 할당하고 초기화합니다.

그러므로 성능이 민감한 상황이라면 가변인수가 걸림돌이 될 수 있습니다.

다행히 이 비용을 감당하면서 가변인수를 사용할 수 있는 적절한 패턴이 있습니다.

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

이런식으로 점층적 패턴을 이용해 가변인수를 사용한다면 매개변수가 2개 이하일 때는 가변인수를 사용하지 않고

매개변수가 3개 이상일 때만 가변인수를 사용하므로 효율적으로 성능 최적화를 이룰 수 있습니다.

6. 가변인수 사용의 적절한 예

EnumSet의 정적 팩터리는 비트 필드를 대체하면서 성능까지도 유지해야하므로

점층적 패턴과 가변인수를 함께 사용한다면 열거 타입 집합 생성 비용을 최소화할 수 있습니다.

7. 정리

이번 포스트는 가변인수에 대해 알아보았습니다.

인수 개수가 일정하지 않은 메서드는 가변인수가 반드시 필요합니다.

하지만 인수를 제한해야 하는 경우가 있을 수 있습니다.

그럴 때는 필수 매개변수를 가변인수 앞에 두고, 성능 문제까지 고려해서 설계해봅시다.

            
              📕 개인 기록용 블로그입니다.
              😊 오타나 잘못된 정보가 있을 경우 댓글이나 메일로 말씀해주시면 바로 수정하겠습니다! 😊
          

댓글남기기