때로는 varags 메소드라고도 불리는 가변 arity 메소드는 임의의 인자(argument) 세트를 받는다. JDK 5.0 이전에는 임의의 인자 세트를 메소드에 패스하려면 오브젝트의 array를 패스해야 했다. 게다가, MessageFormat 클래스의 format 또는 JDK 5.0에 새로 도입된 PrintStream의 printf method와 같은 메소드가 포함된 가변 인자 리스트를 이용하여 존재하는 각 포매팅 스트링에 대해 인자를 추가할 수 없었다. 가변 인자 리스트를 이용하는 이전의 방식은 2002년 2월 4일자 팁 Using Variable Argument Lists(영문)에 설명되어 있다.
JDK 5.0은 훨씬 더 유연한 varags 기능을 추가한다. 그러면, varags 기능에 대해 알아보기 위해 PrintStream 클래스 내 printf 메소드의 JDK 5.0 버전을 살펴보기로 하자.
public PrintStream printf(String format,
Object... args)
이 메소드는 2004년 10월의 테크 팁 Formatting Output With the New Formatter(영문) 에 설명되어 있다.
본질적으로 첫 번째 인자는 후속 인자를 place holders에 기입한 스트링이고, 두 번째 인자에 있는 세 개의 점은 마지막 인자가 인자의 array 또는 sequence로 패스될 수 있음을 나타낸다. 세 개의 점은 C 및 C++ 프로그램에서 가변 인자가 지정되는 방식과 유사하다는 점에 유의하도록 한다.
포매팅 스트링 내의 place holders의 수는 얼마나 많은 인자가 필요한지를 결정하는데, 예를 들어 포매팅 스트링 "Hello, %1s\nToday is %2$tB %2$te, %2$tY"의 경우에는 타입 스트링의 첫 번째 인자와 타입 날짜의 두 번째 인자 등 2개의 인자를 제공한다. 다음은 이에 대한 예제이다.
import java.util.*;
public class Today {
public static void main(String args[]) {
System.out.printf(
"Hello, %1s%nToday is %2$tB %2$te, %2$tY%n",
args[0], new Date());
}
}
이름에 대한 인자를 패스할 경우, 결과는 다음과 같을 것이다.
> java Today Ed
Hello, Ed
Today is October 18, 2005
autoboxing과 unboxing은 (아래의 printf 메소드와 같이) 기본 타입(primitive type) 인자를 제공할 수 있게 해준다.
System.out.printf("Pi is approximately %f", Math.PI, %n);
여기서 Math.PI는 double 타입이고, autoboxing은 이를 Double 타입의 오브젝트로 전환한다. (autoboxing에 관한 자세한 내용을 보려면 2005년 5월 31일자 팁 Autoboxing 소개 내용을 참조할 것.)
가변 인자 리스트를 받기 위해 자체 메소드를 생성할 경우, 메소드의 마지막 인자만이 가변 리스트를 받는 것으로 선언될 수 있다. 가변 길이 인자를 먼저 put할 수는 없다. 예를 들어, 다음 메소드 선언은 유효하며, 가변 수의 String 인자를 받는 하나의 매개변수를 가지는 메소드를 정의한다.
private static void method1(String... args)
가변 인자 매개변수가 유일한 인자일 필요는 없다. 예를 들어, 다음 메소드는 임의의 수의 인자가 따르는 하나의 정수 인자를 취한다.
private static void method2(int arg, Object... args) {
위에 표시한 2개의 포맷을 가지는 메소드를 예제 클래스에 put하면 다양한 수의 인자를 가지는 메소드를 호출할 수 있다.
method1("Hello", "World");
method1(args);
method2(12, 'a', "Hello", Math.PI, 1/3.0);
method2(18, 94.0);
위에서 두번째 호출은 다른 것들과는 약간 다르게 main() 메소드로 들어오는 SString[] 인자를 취하게 된다. varags 퍼실리티는 array를 생성/패스하기 위한 절대 구문(implicit syntax)에 불과하기 때문에, array를 직접 패스할 수 있다. 이 경우, 컴파일러는 array를 수정하지 않은 채 그대로 패스하게 된다.
다음은 두 종류의 메소드를 포함하고 있는 예제 클래스 MyArgs이다.
import java.util.*;
public class MyArgs {
public static void main(String args[]) {
method1("Hello", "World");
method1(args);
method2(12, 'a', "Hello", Math.PI, 1/3.0);
method2(18, 94.0);
}
private static void method1(String... args) {
System.out.println(Arrays.asList(args) +
" // " + args.length);
}
private static void method2(int arg, Object... args) {
System.out.println(Arrays.asList(args) + " / " + arg);
}
}
다음은 MyArgs의 실행 예제이다.
> java MyArgs x y z
[Hello, World] // 2
[x, y, z] // 3
[a, Hello, 3.141592653589793, 0.3333333333333333] / 12
[94.0] / 18
MyArgs는 Arrays.asList() 메소드에 패스함으로써 가변 인자에 액세스한다. 다시 말해서, 인자는 마치 array처럼 액세스되는데, 일반적으로 enhanced for loop에서는 아래와 유사한 형태로 진행될 것이다.
for (String arg: args) {
...
}
이로써 한번에 하나의 엘리먼트를 처리할 수 있게 된다.
보다시피 varargs 기능은 별다른 프로그래밍 없이 가변 수의 인자를 받는 메소드를 정의할 수 있게 해준다. varargs에 관한 자세한 내용은 Varargs(영문)를 참조하기 바란다.
댓글을 달아 주세요
좋은 정보 감사해요~
2007/09/19 05:00