728x90
반응형
private final List<Cheese> cheesesInStock = ...;
/**
* @return 매장 안의 모든 치즈 목록을 반환한다.
* 단, 재고가 하나도 없다면 null을 반환한다.
*/
public List<Cheese> getCheese(){
return cheesesInStock.isEmpty() ? null : new ArrayList<>(cheesesInStock);
}
위의 코드의 문제점은 null을 반환한다는 것이다. 재고가 없다고 해서 특별히 취급할 이유는 없는대도 말이다..
만약에 재고가 없을 경우 null을 반환하는 것을 고집한다면, 이 메소드를 사용하는 모든 클라이언트는 아래와 같은 방어 코드를 넣어줘야 한다.
List<Cheese> cheeses = shop.getCheese();
if(cheeses != null && cheeses.contains(Cheese.STILTON)) ...
방어코드를 빼먹으면 오류가 발생할 수 있을뿐만 아니라, null을 반환하는 쪽에서도 이 상황을 특별히 취급해줘야 하므로 코드가 더 복잡해질 수 있다.
때로는 빈 컨테이너를 할당하는데 비용이 드니 null을 반환하는 쪽이 낫다는 주장이 있는데, 이 주장은 틀린 주장이다.
- 이 할당이 성능 저하의 주범이라고 확인되지 않는 한, 이 정도의 성능 차이는 신경 쓸 수준이 못 된다.
- 빈 컬렉션과 배열은 굳이 새로 할당하지 않고도 반환할 수 있다.
위의 두가지 이유때문이다.
매번 똑같은 빈 불변
컬렉션을 반환하여 빈 컬렉션 할당에 최적화를 시켜줄 수 있다.
알다시피 불변 객체는 자유롭게 공유해도 안전하다.
Collections.emptyList(), Collections.emptySet(), Collections.emptyMap()을 사용하자.
public List<Cheese> getCheese(){
return cheesesInStock.isEmpty() ? Collections.emptyList() : new ArrayList<>(cheesesInStock);
}
배열도 마찬가지이다. 절대 null을 반환하지 말고 길이가 0인 배열을 반환하자.
private static final Cheeses[] EMPTY_CHEESE_ARRAY = new Cheese[0];
public Cheeses[] getCheeses(){
return cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
}
결론
null이 아닌, 빈 배열이나 컬렉션을 반환하라. null을 반환하는 API는 사용하기 어렵고 오류 처리 코드도 늘어난다. 그렇다고 성능이 좋은 것도 아니다.
728x90
반응형
'프로그래밍 노트 > Effective 시리즈' 카테고리의 다른 글
자바 명명규칙 (Naming Rule, Naming Convention) 컨벤션 (0) | 2020.01.12 |
---|---|
매개변수가 유효한지 검사하자 (0) | 2020.01.09 |
스트림은 주의해서 사용해야한다. (0) | 2020.01.06 |
표준 함수형 인터페이스를 사용하자. (0) | 2020.01.01 |
람다보다는 메서드 참조를 사용하라. (0) | 2019.12.26 |