이펙티브 자바, 쉽게 정리하기 - item 54.
null
이 아닌, 빈 컬렉션이나 빈 배열을 반환하라
null
을 반환하는 것의 단점
private final List<Cheese> cheesesInStock = new ArrayList<>();
public List<Cheese> getCheeses() {
return cheesesInStock.isEmpty() ? null
: new ArrayList<>(cheesesInStock);
}
getCheeses()
는cheesesInStock
에 원소가 없으면null
을 반환한다.
이 코드엔 무슨 문제가 있을까?
문제 확인
@Test
public void getCheesesClient() {
List<Cheese> cheeses = getCheeses();
if(cheeses != null && cheeses.contains(Cheese.STILTON)) {
System.out.println("좋았어, 바로 그거야.");
}
}
getCheeses()
를 사용하는 클라이언트 코드는 강제로cheeses != null
과 같이null
을 확인해야 하는 의무를 갖게 된다.- 만일, 빈 리스트를 그냥 반환했다면 따로
null
을 처리할 필요는 없다. null
을 반환함으로써 이 메서드를 사용할 때 고려할 점이 조금 더 늘어난다.
null
을 반환하는 것이 성능상 낫지 않은가?
책에서는 이 물음이 틀렸다고 답한다.
- 물론 새로운 객체를 하나 만들지만 사실상 성능상의 커다란 손해가 없다. (미미하다.)
- 빈 컬렉션과 배열은 굳이 새로 할당하지 않고도 반환 가능하다.
- 빈 컬렉션을 불변으로 선언해놓고 같은 케이스에 계속 재활용해서 할당해도 된다.
Collections.emptyList()
,Collections.emptySet()
,Collections.emptyMap()
도 있다.
null
을 반환하지 않는 실제적인 코드들 1: 컬렉션 생성자 이용
public List<Cheese> getCheeses2() {
return new ArrayList<>(cheesesInStock);
}
ArrayList
의 생성자를 이용하는 방법인데, 이 방법은 사실 객체를 생성하는 방법이다.- 사용 패턴에 따라 정말 가끔이지만 빈 컬렉션 할당이 성능을 떨어뜨릴 가능성도 있다.
null
을 반환하지 않는 실제적인 코드들 2: 컬렉션 말고 배열을 쓴다면, 길이 0 짜리 배열로 나타내기
public Cheese[] getCheeses3() {
return cheesesInStock.toArray(new Cheese[0]);
}
- 배열을 쓸 때도
null
보다 위와 같이 길이 0 짜리 배열을 반환하는 것이 차라리 낫다.
private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];
public Cheese[] getCheeses4() {
return cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
}
- 불변인
EMPTY_CHEESE_ARRAY
를 통해null
대신 빈 배열을 이용해 반환했다. - 길이 0 짜리 배열을 미리
EMPTY_CHEESE_ARRAY
로 선언해두었기 때문에 성능상으로도 문제가 없다.
toArray()
는 배열의 크기에 따라 동작이 달라지는데, 배열이 충분히 크면 원소를 담아 반환하고, 그렇지 않으면 배열을 새로 만들어 그 안에 원소를 담아 반환한다.
핵심 정리
- 배열 혹은 컬렉션을 반환하는 메서드를 구성할 때
null
을 반환하지 말고, 빈 배열 혹은 컬렉션을 반환하자. null
을 반환하면, API를 사용할 때 고려할 게 많고, 코드도 늘어난다. 그렇다고 성능이 좋아지지도 않는다.null
처리를 하는 것을 실수하면, 의도치 않게 NPE 를 만날 수 있다는 것이 치명적이다.
반응형
'Java > 이펙티브 자바' 카테고리의 다른 글
이펙티브 자바, 쉽게 정리하기 - item 56. 공개된 API 요소에는 항상 문서화 주석을 작성하라 (0) | 2023.06.21 |
---|---|
이펙티브 자바, 쉽게 정리하기 - item 55. 옵셔널 반환은 신중히 하라 (0) | 2023.06.20 |
이펙티브 자바, 쉽게 정리하기 - item 53. 가변 인수는 신중히 사용하라 (0) | 2023.06.09 |
이펙티브 자바, 쉽게 정리하기 - item 52. 다중정의는 신중히 사용하라 (0) | 2023.06.09 |
이펙티브 자바, 쉽게 정리하기 - item 51. 메서드 시그니처를 신중히 설계하라 (0) | 2023.06.07 |