[Java] 가변인수 Varargs

Bam·2024년 3월 18일
0

Java

목록 보기
79/98
post-thumbnail

가변인수

그동안 메소드를 선언하고 사용할 때 매개변수 개수를 지정해주어야 했었습니다. 매개변수 개수를 다양하게 하고 싶다면 오버로딩을 이용해서 처리했었고요.

JDK 1.5에서 추가된 가변인수를 이용하면 매개변수를 동적으로 받을 수 있습니다.

가변인수타입...과 같이 작성하여 사용합니다.

public void method(타입... 가변인수명) {}

가변인수는 컴파일 과정에서 배열의 형태로 처리됩니다.

public void method(int... nums) {
	//nums는 int[] nums로 취급
}

만약, 고정된 매개변수와 가변인수를 섞어서 사용한다면 반드시 가변 인수가 매개변수 리스트에서 가장 마지막에 위치해야합니다.

public void method(타입... 가변인수명, 타입 매개변수명) {}	// X 불가능!!!
public void method(타입 매개변수명, 타입... 가변인수명) {}	// O

다음은 가변인수를 사용한 메소드 예제입니다.

public class Main {
    public static void main(String[] args) {
        printNumbers(1);
        printNumbers(1, 2);
        printNumbers(1, 2, 3);
        printNumbers(1, 2, 3, 4);
        printNumbers(1, 2, 3, 4, 5);
    }

    public static void printNumbers(int... nums) {
        for (int num : nums) {	//int[]로 취급되어서 for each 사용 가능
            System.out.println(num + " ");
        }
        System.out.println();
    }
}

오버로딩을 이용했다면 함수를 다섯개 만들어야 했을텐데, 가변인수를 이용하니까 메소드를 하나만 작성하고도 오버로딩한 효과를 얻을 수 있었습니다.


가변인수 사용 주의점

가변인수 메소드의 오버로딩

한 클래스 내부에서 가변인수를 사용한 메소드는 오버로딩을 하지 않는 것이 권장됩니다. 그 이유는 컴파일 과정에서 컴파일러가 어떤 메소드를 사용해야하는지 구분하지 못하는 경우가 발생하기 때문입니다.

public class Main {
    public static void main(String[] args) {
        printNumbers(1, 2, 3);
    }

    public static void printNumbers(int num, int... nums) {
        for (int n : nums) {
            System.out.print(num + " ");
        }
        System.out.println();
    }

    public static void printNumbers(int... nums) {
        for (int num : nums) {
            System.out.println(num + " ");
        }
        System.out.println();
    }
}

위 코드는 printNumbers를 오버로딩한 두 메소드인데요. 메소드를 호출하고 매개변수를 받는 과정에서 num과 nums를 구별하지 못합니다. 따라서 컴파일러는 두 메소드를 구분하지 못하겠다하고 에러를 발생시키게 됩니다.

이런 상황이 나올 수 있기 때문에 같은 클래스 내부에 가변인수를 사용한 메소드가 있다면 해당 메소드는 오버로딩을 하지 않아야합니다.

배열의 문제

가변인수는 컴파일 과정에서 배열로 취급된다고 했습니다. 여기서 두 가지 문제가 발생하는데요.

첫 번째 문제는 배열 타입 매개변수 메소드와 가변인수를 혼용할 수 없는 문제입니다. 컴파일 과정에서 두 메소드 선언은 결국 똑같은 선언이 되어버리기 때문에 가변인수 메소드와 배열 타입 매개변수 메소드를 오버로딩해서 혼용할 수 없습니다.

두 번째 문제는 성능적인 문제입니다. 배열로 취급된다는 것은 컴파일과정에서 배열을 생성하고 그 내부에 전달된 인수들을 담아서 처리한다는 의미가 됩니다. 이는 메소드 실행마다 배열을 생성하고 초기화하는 과정이 포함되기 때문에 특정 상황에서는 성능적인 발목을 잡을 수 있게 됩니다.

그래서 가변인수가 편하다고 막 쓰기보다는 상황에 맞춰서(선언부가 너무 길어지는 4개 이상의 매개변수를 쓰는 상황 등) 가변인수와 오버로딩 중 적절한 것을 선택해서 사용하는 것을 권장드립니다.

0개의 댓글