[이펙티브 자바] 아이템 54. null이 아닌, 빈 컬렉션이나 배열을 반환하라

June·2022년 2월 25일
0

[이펙티브자바]

목록 보기
49/72

만약 null을 반환하면 null을 처리하는 코드를 작성해야 한다.
컬렉션이나 배열 같은 컨테이너가 비었을 때 null을 반환하는 메서드를 사용할 때면 항상 방어 코드를 넣어줘야 한다.

private final List<Cheese> cheesesInStock = ... ;

public List<Cheese> getCheeses() {
    return cheesesInStock.isEmpty() ? null : new ArrayList<>(cheesesInStock);
}
List<Cheese> cheeses = shop.getCheeses();
if (cheeses != null && cheeses.contains(Cheese.STILTON))
    System.out.println("good");

빈 컨테이너를 할당하는 데도 비용이 드니 null을 반환하는 쪽이 낫다는 주장도 있다.
하지만 이것은 틀렸다.

  1. 성능 분석 결과 이 할당이 설능 저하의 주범이라고 확인되지 않는 한 신경 쓸 수준임 못된다.
  2. 빈 컬렉션과 배열은 굳이 할당하지 않고도 반환할 수 있다.
public List<Cheese> getCheeses() {
    return new ArrayList<>(cheesesInStock);
}

가능성은 작지만, 사용 패턴에 따라 빈 컬렉션 할당이 성능을 눈에 띄게 떨어뜨릴 수도 있다. 그러면 매번 똑같은 빈 '불변' 컬렉션을 반환하면 된다.

예를 들어 Colelctions.emptyList, Collections.emptySet, Collections.emptyMap 등이 있다.

배열을 쓸 때도 마찬가지다. null을 반환하지 말고 길이가 0인 배열을 반환하면 된다.

public Cheese[] getCheeses() {
    return cheesesInStock.toArray(new Cheese[0]);
}

이 방식이 성능을 떨어뜨릴 것 같으면 마찬가지로 길이가 0인 배열을 미리 선언해두고 매번 그걸 반환해도 된다.

private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];

public Cheese[] getCheeses() {
    return cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
}

단순히 성능 개선이 목적이라면 미리 할당된 배열이 오히려 성능이 떨어진다는 연구 결과도 있다.

0개의 댓글