-
가변인자(varargs)는 실제 런타임(Runtime) 시 어떻게 작동 할까?Develop/Java 2022. 9. 13. 11:19
가변인자 란?
- 기존에는 메서드의 매개변수의 개수가 고정적이어서 컬렉션이나 배열을 통해 사용했다.
- JDK1.5부터 동적으로 매개변수를 지정하는 가변인자라는 것이 생겼다.
- 아래와 같이 파라미터 변수에 ...을 파라미터 변수명 앞에 붙여주면 된다.
public void testVarargs(String... d) { //... }- 가변인자를 사용하는 대표적인 메소드는 PrintStream의 printf()이다.
/* * @since 1.5 */ public PrintStream printf(String format, Object ... args) { return format(format, args); }사용 시 주의 할 점
- 가변인자는 여러개 사용될 수 없고, 가변인자는 항상 마지막에 있어야 한다. (가변인자인지 아닌지를 구분할 방법이 없기 때문)

- 가변인자 사용 시 인자를 넣지 않아도 정상적으로 실행이 된다.

- 가변인자 앞에 동일한 타입의 매개변수를 오버로딩 시 구별 못한다는 이유(ambiguous)로 허용하지 않는다.

매개변수를 가변인자와 배열로 선언하는 것과 차이?
- 배열타입의 경우 반드시 인자를 지정해줘야하기 때문에 인자를 생략할 수가 없다. (null이나 0인 배열을 인자로 지정해줘야 함)

바이트코드에서 확인
소스 코드
import java.util.Arrays; public class TestV { public static void main(String[] args) { varargsTest(5, "1", "2", "3"); } public static void varargsTest(int a, String... str) { System.out.println(Arrays.toString(str)); } }- Arrays.toString을 활용해야 하는 것을 보아 가변인자를 거쳐서 넘어오는 args의 인자들은 배열의 형태로 변환된다는 사실을 확인할 수 있다.
바이트 코드
public static main([Ljava/lang/String;)V // parameter args L0 LINENUMBER 9 L0 ICONST_5 ICONST_3 ANEWARRAY java/lang/String // 객체 타입 배열 생성 DUP ICONST_0 LDC "1" AASTORE // 배열에 "1" 저장 DUP ICONST_1 LDC "2" AASTORE // 배열에 "2" 저장 DUP ICONST_2 LDC "3" AASTORE // 배열에 "3" 저장 INVOKESTATIC com/example/test/TestV.varargsTest (I[Ljava/lang/String;)V // varargsTest 메소드 호출, [Ljava/lang/String;) 가변인자 호출 L1 LINENUMBER 10 L1 RETURN L2 LOCALVARIABLE args [Ljava/lang/String; L0 L2 0 MAXSTACK = 5 MAXLOCALS = 1 // access flags 0x89 public static varargs varargsTest(I[Ljava/lang/String;)V // parameter a // parameter str L0 LINENUMBER 13 L0 GETSTATIC java/lang/System.out : Ljava/io/PrintStream; ALOAD 1 INVOKESTATIC java/util/Arrays.toString ([Ljava/lang/Object;)Ljava/lang/String; INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V L1 LINENUMBER 14 L1 RETURN L2 LOCALVARIABLE a I L0 L2 0 LOCALVARIABLE str [Ljava/lang/String; L0 L2 1 // str 매개변수가 [Ljava/lang/String;(일반 배열형태로) 변환됨을 확인할 수 있다. MAXSTACK = 2 MAXLOCALS = 2 }결론
- ...이라는 표시를 해두면 컴파일러는 배열 형태로 바꾼다.
- 매개변수 파라미터를 배열로 하는경우는 인자를 반드시 넣어야 하지만(null 이나 0인 배열), 가변인자는 그렇지 않다.