Skip to content

Latest commit

 

History

History
66 lines (50 loc) · 2.55 KB

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

File metadata and controls

66 lines (50 loc) · 2.55 KB

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

가변 인수란?

0개 이상의 유동적인 개수의 인수를 허용하는 인수

→ 가변 인수 메소드가 호출 되면 가변 인수의 개수와 같은 길이의 배열을 만들고 인수들을 저장하여 가변 인수 메소드에 건내준다.

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

위는 가변인수를 받아 합을 반환하는 메소드인데, 가변 인수의 개수가 0도 허용된다.

그렇다면 아래와 같이 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개인 문제가 컴파일 시점이 아닌 런타임 시점에 발생한다는 것이다.

또한, 유효성 검사를 명시해야하고, min의 초기값을 Integer.MAX_VALUE로 설정하지 않고는 보다 명료한 for-Each 문을 사용할 수 없다.

다행이 아래와 같은 방법으로 해결할 수 있다.

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

평범한 매개변수 1개, 가변인수 1개를 받게하면 문제가 사라진다. 평범한 매개변수 1개를 통해 로직을 위한 값이 1개 이상임을 보장할 수 있고 있고, 런타임 에러도 발생하지 않는다. 만약 해당 메소드를 호출하는 곳에서 값이 0개 미만이라면 에러는 런타임이 아닌 컴파일 시점에서 발생할 것이다.

또한, 가변 인수는 호출 될 때 마다 새로운 배열을 생성하고 초기화 하기 때문에 성능적인 단점을 가진다.

만약, 위의 성능 단점을 안고 가기 싫지만 가변 인수의 유연성을 얻고 싶다면 아래와 같은 구조를 적용해보자.

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

만약, 인자가 3개 이하인 경우가 95%라면 해당 메소드를 사용할 때 배열을 새로 생성하는 경우는 5%밖에 없다. 이렇게 인자 개수의 비율을 고려하면서 해당 구조를 적용해야한다.