프로그래밍Java 개발자

자바에서 varargs(가변 인자)란 무엇이며, 어떻게 작동하며, 사용할 때 어떤 함정이 있을까요?

Hintsage AI 어시스턴트로 면접 통과

대답

Varargs는 메소드가 하나의 타입에 대해 가변 개수의 인자를 받을 수 있게 해주는 문법입니다. 세 점으로 선언됩니다:

public void printNames(String... names) { for (String name : names) { System.out.println(name); } }

어떻게 작동할까요?

Varargs 파라미터는 메소드 내부에서 해당 타입의 배열입니다: 위의 예에서 String[] names. 메소드는 임의의 개수의 인자나 배열로 호출될 수 있습니다:

printNames("Igor", "Anna", "Maria"); printNames(new String[] {"Alex", "Inna"});

사용의 주의사항:

  • Varargs는 메소드 파라미터 목록의 마지막 파라미터여야 합니다.
  • 한 메소드에 varargs 파라미터는 하나만 허용됩니다.
  • 배열과 varargs, 그리고 서로 다른 타입의 varargs 간의 오버로드가 있을 경우 모호한 호출이 발생할 수 있습니다.
  • null을 varargs에 전달할 경우, 메소드는 빈 배열이 아닌 null을 받습니다!

트릭 질문

질문: 인자를 전달하지 않고 메소드를 호출하면 varargs 파라미터의 배열 길이는 얼마일까요?

답변: 이 경우 varargs는 길이가 0인 배열을 참조하게 됩니다: new String[0]. null이 아닙니다!

public void foo(Integer... args) { System.out.println(args.length); } // foo(); // 출력: 0

주제로 인한 실수의 실제 사례


이야기

로깅 라이브러리에 log(String... messages) 메소드가 있었습니다. log(null)을 호출할 때 내부에서 NullPointerException이 발생했습니다(빈 배열 대신 messages가 null로 예상됨). 이를 해결하기 위해 명시적으로 null을 확인해야 했습니다.


이야기

개발자는 오버로드를 만들었습니다:

public void doSomething(String[] arr) {...} public void doSomething(String... arr) {...}

배열을 전달했을 때, 예상했던 메소드가 호출되지 않아 일부 데이터가 손실되었습니다. 배열과 varargs의 차이가 명확하지 않았습니다.


이야기

프로젝트에 varargs 뒤에 두 번째 파라미터를 추가했습니다:

public void foo(String... args, int count) {...} // 컴파일 오류!

이는 오류를 발생시키고 빌드를 중단시켰습니다. varargs는 마지막이어야 하기 때문입니다.