Adventure Time - Lady Rainicorn [아이템 53] 가변인수는 신중히 사용하라
본문 바로가기
🤓 스터디/이펙티브 자바

[아이템 53] 가변인수는 신중히 사용하라

by 강켄트 2023. 4. 18.

 

인수 개수가 일정하지 않은 메서드를 정의해야 하는 상황이라면 가변인수는 아주 유용하다.

가변인수를 사용할 때 고려해야 할 점들이 이번 아이템의 주제이다.

 

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

가변인수 메서드를 호출하면, 가장 먼저 인수의 개수와 길이가 같은 배열을 만들고

인수들을 이 배열에 저장하여 가변인수 메서드에 건네준다.

 

다음은 가변인수 메서드를 잘못 구현한 예이다.

53-2) 인수가 1개 이상이어야 하는 가변인수의 잘못 구현한 예 

public class MinTest {
    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;
    }

    public static void main(String[] args) {
        System.out.println(min());
    }
}

//Exception in thread "main" java.lang.IllegalArgumentException: 인수가 1개 이상 필요합니다.

 

위의 코드의 min은 인수가 1개 이상이어야 하는 최솟값을 찾는 메서드인데,

인수를 0개만 받을 수도 있도록 설계하는 건 좋지 않다.

인수를 0개 넣고 호출하면 런타임에 실패하기 때문이다.

이처럼 인수 개수는 런타임에(자동 생성된) 배열의 길이로 알 수 있다.

 

더 나은 방법

매개변수를 2개 받도록 작성하자

53-3) 인수가 1개 이상이어야할 때 가변인수를 제대로 사용하는 방법

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

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

 

❗️ 가변인수 사용시 주의해야 할 점

성능에 민감할 수 있다.

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

 

성능 이슈로 가변인수 대신 선택할 수 있는 대안

▶️ 다중정의 메서드를 사용하자

 

메서드 호출의 95%가 인수를 3개 이하로 사용한다고 가정할 때 

인수가 0개인 것부터 4개인 것까지, 총 5개를 다중정의하면 마지막 다중정의 메서드가 인수 4개 이상인 5%의 호출을 담당할 수 있다.

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){  }

 

 

정리

가변인수 메서드를 정의할 때 매개변수 2개(첫번째로 필수 매개변수, 두 번째로 가변인수)!

성능 이슈도 고려하자 

 

 

 

 

 

댓글