아이템 53. 가변인수는 신중히 사용하라
가변인수 메서드는 자바 5에 추가된 친구입니다. 가변인수 메서드를 사용하면 명시한 타입의 인수를 0개 이상 받을 수 있습니다. 얘를 호출하면, 먼저 인수의 개수와 길이가 같은 배열을 만들고 인수들을 이 배열에 저장해서 가변인수 메서드에게 건네줍니다.
다음은 입력받은 int 인수들의 합을 계산해주는 가변인수 메서드입니다. sum(1, 2, 3); 을 호출하면 6을, sum() 을 호출하면 0을 반환합니다.
static int sum(int... args) {
int sum = 0;
for (int arg : args)
sum += arg;
return sum;
}
인수가 한 개 이상이어야 하는 경우도 있을 수 있습니다. 최솟값을 찾는 메서드인데 인수를 0개 받도록 하면 좋지 않습니다.
static int min(int... args) {
if (args.length == 0)
throw new IllegalArgumentException("인수가 1개 이상 필요합니다.");
int min = args[0];
for (int i = 1; i < args.length; i++)
if (args[i] < min)
min = args[i];
return min;
}
이 메서드의 가장 큰 문제점은 컴파일 시점이 아닌 런타임 시점에 실패한다는 점입니다. 코드도 더럽고요. 이런 경우에는 매개변수를 두 개 받도록 하면 됩니다. 첫 매개변수로는 그냥 하나 받고, 가변인수는 두 번째로 받으면 됩니다.
static int min(int firstArg, int... remainingArgs) {
int min = firstArg;
for (int arg : remainingArgs)
if (arg < min)
min = arg;
return min;
}
아이템 54. null이 아닌, 빈 컬렉션이나 배열을 반환하라
만약 어떠한 리스트나 배열을 반환하는 메서드에서 넘겨줄 원소가 하나도 없을때, null 을 반환한다면 클라이언트 쪽에서 이러한 null 상황을 처리하는 코드를 추가로 작성해주어야 합니다.
List<Cheese> cheeses = shop.getCheeses();
if (cheeses != null && ~~)
System.out.println("굿");
빈 컨테이너를 메모리에 할당하는데도 비용이 드니깐 null 을 반환하는 것이 낫다는 주장도 있다는데용. 이는 두 가지 측면에서 틀린 주장이라고 합니다. 먼저, 성능 분석 결과 이 할당이 유의미한 성능 차이를 주진 않고, 두 번째로는 빈 컬렉션과 배열은 굳이 새로 할당하지 않고도! 반환할 수 있다는 점입니다. 대부분의 상황에서 이렇게 반환해주면 됩니다.
public List<Cheese> getCheeses() {
return new ArrayList<>(cheeseInStock);
}
마아아안약에 빈 컬렉션 할당이 성능을 눈에 띄게 저하시킨다면, 해법은 간단합니다. 매번 똑같은 빈 불변 컬렉션을 반환하는 것입니다. 다음 코드에서 사용하는 Collections.emptyList 메서드가 그러한 예입니다.
public List<Cheese> getCheeses() {
return cheesesInStock.isEmpty() ? Collections.emptyList() : new ArrayList<>();
}
배열의 경우도 마찬가지로 null 을 넘겨주지 말고 길이가 0인 배열을 반환하도록 합시다.
public Cheese[] getCheeses() {
return cheesesInStock.toArray(new Cheese[0]);
}
마아아아아안약에 성능 저하가 걱정된다면, 길이 0짜리 배열을 미리 선언해놓고 매번 그 배열을 반환하면 됩니다. 길이 0인 배열은 모두 불변이니까요.
private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];
public Cheese[] getCheeses() {
return cheeseInStock.toArray(EMPTY_CHEESE_ARRAY);
}