private final List<Cheese> cheesesInStock = ...;
/**
* @return 매장 안의 모든 치즈 목록을 반환한다.
* 단, 재고가 하나도 없다면 null을 반환한다.
*/
public List<Cheese> getCheeses() {
return cheesesInStock.isEmpty() ? null
: new ArrayListo( cheesesInStock);
}
→ 클라이언트는 null 처리 코드를 추가로 작성해야 하며, 처리 코드가 없을 경우 오류가 발생할 수 있다.
빈 컨테이너를 할당하는 데도 비용이 드니 null을 반환하는 쪽이 낫다는 주장도 있지만,
- 성능 분석 결과 빈 컨테이너를 할당하는 것이 성능 저하의 주범이라고 확인되지 않는 한, 이 정도의 성능 차이는 신경 쓸 수준이 못 된다.
- 빈 컬렉션과 배열은 굳이 새로 할당하지 않고도 반환할 수 있다.
이 두 가지 면에서 틀린 주장이라고 볼 수 있다.
#1. 컬렉션
public List<Cheese> getCheeses() {
return new ArrayListo(cheesesInStock);
}
→ 빈 컬렉션을 반환하는 전형적인 코드이다.
가능성은 작지만, 사용 패턴에 따라 빈 컬렉션 할당이 성능을 눈에 띄게 떨어뜨릴 수도 있다.
이 문제는 매번 똑같은 빈 불변 컬렉션을 반환하면 해결된다!
불변 객체는 자유롭게 공유해도 안전하다.
public List<Cheese> getCheeses() {
return cheesesInStock.isEmpty() ? Collections.emptyList()
: new ArrayListo(cheesesInStock);
}
→ 위 코드처럼 빈 불변 컬렉션을 사용하는 것은 최적화에 해당하니 꼭 필요할 때만 구현하는 것이 좋다.
#2. 배열
절대 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 cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
}
컬렉션과 비슷하게 단순히 성능을 개선할 목적이라면,
toArray에 넘기는 배열을 미리 할당하는 건 추천하지 않는다. (오히려 성능이 떨어질 수도 있다!)
null이 아닌, 빈 배열이나 컬렉션을 반환하라. null을 반환하는 API는 사용하기 어렵고 오류 처리 코드도 늘어난다. 그렇다고 성능이 좋은 것도 아니다.
'Effective Java' 카테고리의 다른 글
[Effective Java] 아이템 56 - 공개된 API 요소에는 항상 문서화 주석을 작성하라 (0) | 2022.05.09 |
---|---|
[Effective Java] 아이템55 - 옵셔널 반환은 신중히 하라 (0) | 2022.05.04 |
[Effective Java] 아이템 53 - 가변인수는 신중히 사용하라 (0) | 2022.05.04 |
[Effective Java] 아이템 52 - 다중정의는 신중히 사용하라 (0) | 2022.05.04 |
[Effective Java] 아이템 51 - 메서드 시그니처를 신중히 설계하라 (0) | 2022.04.05 |