Home [Effective Java] Item53. 가변인수는 신중히 사용하라!
Post
Cancel

[Effective Java] Item53. 가변인수는 신중히 사용하라!

Item53. 가변인수는 신중히 사용하라!

가변인수

  • 가변인수(varargs) 메서드는 명시한 타입의 인수를 0개 이상 받을 수 있다.
  • 가변인수 메서드를 호출하면, 가장 먼저 인수의 개수와 길이가 같은 배열을 만들고, 인수들을 배열에 저장하여 가변인수 메서드에 전달한다.

간단한 활용 예시

1
2
3
4
5
6
7
public int sum(int... args) {
    int sum = 0;
    for (int arg : args) {
        sum += arg;
    }
    return sum;
}

인수를 받아야 할 때

잘못 사용한 예

1
2
3
4
5
6
7
8
9
10
11
static int sum(int... numbers) {
    if (numbers.lenght == 0) {
      throw new IllegalArgumentException("인수가 1개 이상 필요합니다.");
    }
    int sum = 0;
    for (int number : numers) {
      sum += number;
    }

    return sum;
}
1
2
3
sum(1); // 1
sum(1, 7); // 8
sum(); // error
  • 이렇게 오류를 던지도록 하는 방식은 좋지 않다.
    • 컴파일 타임이 아닌 런타임에 실패한다.
    • 코드가 지저분해진다.

올바르게 사용한 예

1
2
3
4
5
6
7
8
static int sum(int firstNumber, int... numbers) {
	int sum = firstNumber;
	for (int number : numers) {
		sum += number;
	}
	
	return sum;
}
  • 가변인수 매개변수를 하나만 받는 것보다 위의 코드처럼 매개변수를 2개 받도록 하면 된다.
    • 사용해야 하는 필요한 매개변수는 평범하게 받고, 가변인수를 두 번째 매개변수로 받는다.

주의할 점

  • 성능에 민감한 상황이라면 가변인수가 걸림돌이 될 수 있다.

    • 가변인수 메서드는 호출될 때마다 배열을 새로 하나 할당 및 초기화한다.
  • 성능 저하를 최소화하기 위해 메서드 오버로딩을 사용할 수 있다.

    1
    2
    3
    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... args) {}
    
    • 인수 3개 이하가 95%의 사용량을 차지하고, 나머지가 5%를 차지한다고 가정해보자.
      • 다중정의 메서드를 통해 가변인수를 사용하게 되는 매개변수를 4개 이상 받는 경우는 5% 밖에 되지 않는다.
      • 이러한 방법을 사용해 유연성을 지키면서 성능을 최적화할 수 있다.
      • 이러한 전략을 사용한 대표적인 예는 EnumSet의 정적 팩터리다. 이 기법을 통해 열거 타입 집합 생성 비용을 최소화한다.

핵심 정리

  • 인수 개수가 일정하지 않은 메서드를 정의해야 한다면 가변인수가 반드시 필요하다.
  • 메서드를 정의할 때 필수 매개변수는 가변인수 앞에 두고, 가변인수를 사용할 때는 성능 문제를 고려해 사용하자.
This post is licensed under younghwani by the author.

[Effective Java] Item52. 다중정의는 신중히 사용하라!

[Effective Java] Item54. null이 아닌, 빈 컬렉션이나 배열을 반환하라!

Comments powered by Disqus.