자 바 5.0에서 소개되는 기법 중에서 가변인수(Varargs)라는 것이 있다. 가변인수라는 것은 필요에 따라 매개변수(인수)를 가변적으로 조정할 수 있는 기술이다. 가변인수가 없던 시절에는 가변인수 대신 컬렉션이나 배열을 이용해서 가변인수를 대체하고 있었다.
□ 가변인수가 없던 시절
◇ 컬렉션이나 배열을 이용해서 가변인수를 대체하고 있었다.
우선 컬렉션을 이용해서 가변인수를 사용하던 기법부터 보도록 하자. 다음은 인수를 Vector에 넣어서 메서드로 전달하는 예이다.
▒ 컬렉션을 이용한 가변인수(메서드)
1 2 3 4 5 6 7 | public class VarArgsMain {
public static void display(Vector v) {
for (Object s : v) {
System.out.println("컬렉션형태:" + s);
}
}
}
|
▒ 컬렉션을 이용한 가변인수(호출)
1 2 3 4 5 | Vector vec = new Vector ();
vec.add("Hello");
vec.add("World");
vec.add("Korea");
VarArgsMain.display(vec);
|
위의 예에서 Vector에 데이터를 원하는 만큼 넣어서 메서드 내부로 전달할 수 있다. 하지만 자바 5.0에서는 가변인수 기법 자체를 이용하면 보다 쉽게 가변인수를 적용할 수 있다. 다음은 가변인수를 적용하는 예이다.
▒ 가변인수를 이용한 메서드
1 2 3 4 5 6 7 | public class VarArgsMain {
public static void display(String... strs) {
for (String s : strs) {
System.out.println("가변인수형태:" + s);
}
}
}
|
▒ 가변인수를 이용한 메서드의 호출
1 | VarArgsMain.display("Hello" , "World", "Korea");
|
가변인수를 테스트하는 전체 예는 다음과 같다.
§ chap07\VarArgsMain.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /**
컬렉션과 가변배열의 차이
**/
import java.util.*;
public class VarArgsMain {
public static void display(Vector v) {
for (Object s : v) {
System.out.println("컬렉션형태:" + s);
}
}
public static void display(String... strs) {
for (String s : strs) {
System.out.println("가변배열형태:" + s);
}
}
public static void main(String[] args) {
Vector vec = new Vector ();
vec.add("Hello");
vec.add("World");
vec.add("Korea");
VarArgsMain.display(vec);
VarArgsMain.display("Hello" , "World", "Korea");
}
}
/***
컬렉션형태:Hello
컬렉션형태:World
컬렉션형태:Korea
가변배열형태:Hello
가변배열형태:World
가변배열형태:Korea
***/
|
가변인수는 특별할 것이 없다. 단지 가변인수를 선언할 때 ...을 붙여주기만 하면 된다. 그 다음은 컴파일러가 알아서 해준다.
사 실 가변인수도 컴파일러의 눈속임에 가깝다. ...이라는 표시를 해두면 컴파일러는 이것을 배열형식으로 바꾸어버린다. 그리고 매개변수로 주어지는 가변인수들을 모아서 배열 객체로 만들어 버린다. 결국 컴파일러가 해주는 일은 다음과 같이 정리할 수 있다.
□ 가변인수에서 컴파일러가 해주는 일
◇ 매개변수를 배열로 변환해준다.
― 원본 : public static void display(String... strs)
― 컴파일러 변환 후 : public static void display(String as[])
◇ 메서드 호출 시 인자들을 이용해서 배열로 만들어 준다.
― 원본 : VarArgsMain.display("Hello", "World", "Korea");
― 컴파일러 변환 후 : VarArgsMain.display(new String[] {"Hello", "World", "Korea" });
이 것을 확인하기 위해서 jad 역컴파일러를 이용해서 역컴파일을 해보면 쉽게 알 수 있다. 앞에서 우리는 가변인수를 사용한 적이 있다. String.format()을 학습할 때 가변인수에 대한 설명 없이 포멧 지정자를 여러 개 사용하였다. format()의 매개변수로 사용자가 원하는 만큼의 포멧 지정자를 사용할 수 있는 것은 가변인수를 지원하기 때문이다. 다시 한번 확인해보기 바란다.