✏️개요
이번에 작성할 게시글의 주제는 가변 인자(Varargs)이다. 필자는 이 가변 인자 역시 학부생 시절이나 취업을 준비하는 과정에서 접해본 적 없던 개념이었다. (뭐 이렇게 처음 보는 게 많은 건지) 가변 인자를 처음 접하게 된 것은 역시 현재 실무에서 분석하고 있는 프로젝트에서 접할 수 있었다. 이 과정에서 Java의 Reflection이라는 개념도 접하였는데, 이에 대한 게시글은 다음에 작성하고자 한다.
❗ 본 게시글은 필자 개인적인 의견이므로 틀린 부분이 있을 수 있습니다. 댓글을 통해 지적해주시면 감사하겠습니다.
✏️Varargs, 가변 인자
필자는 처음에는 가변 인자라는 단어 자체도 모르고 있던 상태에서, 프로젝트에서 아래와 같은 형식의 문법을 발견할 수 있었다.
public Object list(String str, boolean bol, Object... params){...}
물론 자세한 코드는 위와 다르지만, 어떠한 리스트를 가져오는 메서드에서 사용되는 매개 변수 중 Object... 부분이 눈에 띄게 되었다. 처음 보는 형식의 문법이었기에 이를 알아보기 위해 검색하는 것부터가 난관이었다. 그러다 문뜩... 이 무언가 변할 수 있다는 의미라는 느낌이 들어 가변 인자라고 검색을 했고, 적중했다.
가변 인자라는 단어를 통해 유추한 의미 또한 적중하였는데, 가변 인자는 말 그대로 인자로 전달할 수 있는 값이 가변적이라는 것이다.
하나 짚고 넘어가자. 매개 변수는 메서드에서 전달받을 때 사용하는 말 그대로 변수이고, 인자는 이 매개 변수에게 넘겨주는 값을 의미한다.
✏️가변 인자를 사용하지 않을 때
Oracle의 Java Documentation에서 Varargs에 대한 설명의 시작은 가변 인자를 사용하지 않을 때의 예제를 MessageFormat 클래스를 통해 들고 있다.
Object[] arguments = {
new Integer(7),
new Date(),
"a disturbance in the Force"
};
String result = MessageFormat.format(
"At {1,time} on {1,date}, there was {2} on planet "
+ "{0,number,integer}.", arguments);
MessageFormat 클래스는 데이터를 정해진 양식에 맞게 출력할 수 있게 만들어주는 클래스이며, format(정해진 양식, 양식에 사용할 데이터의 집합)을 이용한다고 한다. 위의 코드에 대해서 간략히 써보면
- String result는 format()을 이용해 정해진 양식으로 문자열이 저장되는 변수.
- Object [] arguments는 객체들의 배열, format()의 두 번째 매개 변수로 전달된다.
- format()은 전달받은 arguments 배열의 인덱스를 참조해 {1}, {0}과 같은 형식으로 값을 가져온다. (time, date, number, integer은 MessageFormat 클래스에서 지원하는 내장 타입이다.)
즉, 가변 인자를 사용하지 않는 경우, format() 메서드의 두 번째 인자에 여러 값을 전달하기 위해서는 해당 값들의 Object 배열 또는 여타 다른 Collection Framework를 이용해 전달해야 한다.
이를 위해선 배열 또는 컬렉션 클래스들에 대한 객체를 생성하고... 값을 담고... 하는 과정이 필수적으로 존재해야 한다.
✏️가변 인자를 사용할 때
이제 가변 인자를 사용하면 다음과 같이 사용할 수 있다.
String result = MessageFormat.format(
"At {1,time} on {1,date}, there was {2} on planet "
+ "{0,number,integer}.",
7, new Date(), "a disturbance in the Force");
format() 메서드의 두 번째 인자를 보면, 더 이상 arguments의 배열이 아닌 배열 속에 들어있던 값들이 차례로 나열되어 있다. 원래 1개의 배열이 인자로서 전달되었던 코드가 3개의 Object 객체로 전달되고 있다. 또한 기존에 배열을 선언하던 코드가 사라졌다.
실제로 MessageFormat 클래스의 format() 메서드의 정의는 public static String format(String pattern, Object... arguments)로, 가변 인자를 사용한다. 그러나 가변 인자를 사용하지 않고 배열을 넘겨주었을 때 정상적으로 동작한 이유는 가변 인자가 내부적으로 배열을 사용한다고 한다.
즉, 가변 인자를 사용함으로써 우리는 배열을 생성하고 값을 할당하는 과정을 직접 처리하지 않게 된 것이다.
The varargs feature automates and hides the process.
✏️참고 사항
- 가변 인자 사용 시 인자를 넘겨주지 않아도 에러가 발생하지 않는다.
- 그렇기 때문에, 매개 변수로 받아서 추가적인 로직 구현 시 이에 대해 충분히 고려해야 한다.
- 가변 인자 사용 시 다른 매개 변수가 존재한다면, 가변 인자를 위한 매개 변수는 가장 마지막에 사용되어야 한다.
- 가변 인자가 사용된 메소드는 오버 로딩 시 모호함이 있기 때문에 에러가 발생한다.
- 따라서, 가변 인자를 사용한 메소드는 오버 로딩을 사용하지 않는 것이 좋다.
✏️마치며
가변 인자에 대해서 몰랐던 부분을 알 수 있었다. Oracle의 Java Documentation의 설명의 하단에는 우연히 Reflection의 예제를 이용해서 가변 인자에 대해 설명하는 부분이 존재하던데 다음 글의 주제인 Reflection에 대해 알아볼 때 도움이 될 것 같다.