Java
에서는 매개변수의 타입이나 개수가 다르다면 같은 클래스 안에서도 중복된 이름의 메서드를 정의할 수 있음. 이처럼 같은 이름의 메서드 여러개를 정의하는 것을 메서드 오버로딩(method overloading)이라고 하고, 줄여서 오버로딩이라 함.
메서드의 이름이 같아야 함
매개변수의 타입과 개수, 혹은 순서가 달라야 함
[유의] 매개변수 순서가 다른 경우도 오버로딩으로 간주
long add(int a, long b) { return a + b; } long add(long a, int b) { return a + b; }
반환값 타입은 영향 없음
int add(int a, long b) { return a + b; } long add(long a, int b) { return (long)(a + b); } // 오버로딩이 아님. 중복 선언 에러 발생
println
메서드
이 메서드는 사실 하나가 아님. println
이 속한 클래스 PrintStream
에는 매개변수의 타입에 따라 각기 다른 println
메서드가 정의되어 있음.
public class PrintStream {
...
void println();
void println(boolean x);
void println(char x);
void println(int x);
void println(float x);
... // 이런 식으로 오버로딩되어 있음
}
오버로딩을 위해 매개변수의 개수를 달리하여 동일한 이름과 기능을 하는 메서드를 정의하다보면, 매개 변수의 개수의 가변성에 따른 케이스들을 대비해 수많은 메서드를 정의해야 하는 상황이 생김. 이러한 불편함을 덜어줄 수 있는 것이 바로 가변인자(variable arguments).
가변인자(variable arguments)는 JDK
1.5부터 지원하는 기능으로, 매개변수의 개수를 동적으로 지정할 수 있게 해줌.
타입... 매개변수명
가변인자 활용의 대표적인 예로 printf
메서드가 있음
public PrintStream printf(String format, Object... args) { ... }
// 첫번째 인자: 지시자를 포함한 formatting된 문자열
// 두번째~n번째 인자: 지시자에 대입될 리터럴이나 변수 (인자의 개수는 가변적)
📌 [주의] 가변 인자는 위치상 맨 마지막에 있어야함.
가변인자는 내부적으로 배열을 이용함. (메서드가 호출될 때마다 배열을 새로 생성)
매번 새로운 배열을 생성하는 것은 메모리 효율로 봤을 때 좋지 않음. 가변인자의 신중한 사용 필요
매개변수에 배열을 넣을 때는 인자 생략 불가능. 인자가 없는 경우(null
)와 인자 배열의 길이가 0인 경우에도 명시를 해주어야함. 반면, 가변인자는 인자 생략이 가능함 (추가 고려할 사항 없음)
// 배열 사용
int sum(int[] numArr) { ... }
int result = sum(); // (X)
int result = sum(null); // 인자가 없는 경우 (O)
int result = sum(new numArr[0]); // 인자 배열의 길이가 0인 경우 (O)
// 가변인자 사용
int sum(int... nums) { ... }
int result = sum(); // 인자가 없어도 되기 때문에 이렇게 괄호를 비워도 됨 (O)
static String concatenate(String bridge, String... args) {
String result = "";
for (String arg : args) {
result += arg + bridge;
}
return result;
}
static String concatenate(String... args) {
return concatenate("", args);
}
위 두 메서드는 오버로딩이 불가하여 공존할 수 없음.
컴파일러는 가변인자가 포함된 메서드를 잘 구분하지 못하므로 가능하면 가변인자를 활용한 메서드는 오버로딩 하지 않는 것이 좋음.