핵심 정리
null이 아닌 빈 배열이나 컬렉션을 반환하라. 성능적으로도 좋고 오류 처리 코드도 필요 없다.
null을 반환하는 메소드
// 잘못된 예
private final List<Cheese> cheesesInStock = ...;
/**
* @return 매장 안의 모든 치즈 목록을 반환한다.
* 단, 재고가 하나도 없다면 null을 반환한다.
*/
public List<Cheese> getCheeses() {
return cheesesInStock.isEmpty() ? null : new ArrayList<>(cheesesInStock);
}
위 코드는 NullPointerException을 발생시키는 경우가 많으며, 이에 따라 디버깅이 어렵게 된다.
// 방어 코드
List<Cheese> cheeses = shop.getCheeses();
if (cheeses != null && cheeese.contains(Cheese.STILTON))
System.out.println("좋았어, 바로 그거야.");
또한, 이 메소드를 사용하는 클라이언트 코드는 항상 반환된 결과가 null인지 확인해야 한다.
빈 컬렉션 반환 메소드
null 대신 빈 컨테이너를 할당한다면, 방어 코드를 작성할 필요가 없어진다.
public List<Cheese> getCheeses () {
return new ArrayList<>(cheeseInStock);
null을 반환하는 것보다 빈 컬렉션을 반환하는 게 더 좋은가?
때로는 사용 패턴에 따라 빈 컬렉션 할당이 성능을 눈에 띄게 떨어뜨릴 수 있다. 이런 경우는 불변 컬렉션을 반환하여 최적화 가능하다.(불변 객체는 자유롭게 공유해도 안전하다. 아이템 17)
내부가 빈 불변 컬렉션
- Collections.emptyList
- Collections.emptySet
- Collections.emptyMap
위 내용을 고려하여 아래처럼 수정할 수 있다.
// 최적화 - 빈 컬렉션 매번 새로 할당 X
public List<Cheese> getCheese() {
return cheesesInStock.isEmpty() ?
Collections.emptyList() : new ArrayList<>(cheesesInStock);
}
빈 배열 반환 메소드
: 절대 null을 반환하지 말고 길이가 0인 배열을 반환하라.
아래처럼 반환 타입(Cheese[])을 알려주는 역할을 하는 빈 배열을 반환할 수 있다.
public Cheese[] getCheeses() {
return cheesesInStock.toArray(new Cheese[0]);
}
마찬가지로 아래처럼 최적화할 수 있다.
// 최적화 - 빈 배열을 매번 새로 할당 X
private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];
public Cheese[] getCheeses() {
return cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
}
toArray() 주의해야 할 점
: toArray(new T[0])와 toArray(new T[t.size()])의 차이
- toArray(new T[0])
- 새로운 배열을 만들어 그 배열을 반환
- Java 8 이후부터는 배열의 크기를 0으로 설정하여 toArray를 호출하면 JVM 내부에서 최적화가 이루어짐
- JVM이 배열의 적절한 크기를 결정하고, 필요한 경우 새로운 배열을 만들어서 반환
- toArray(new T[t.size()])
- 리스트의 크기만큼의 배열을 미리 생성하여 toArray에 전달
- toArray 메소드가 새로운 배열을 생성하지 않고, 전달된 배열을 그대로 사용하여 원소들을 저장하고 반환
- 리스트의 크기만큼의 배열을 미리 생성하므로 메모리 할당 비용 발생
최신 JVM에서는 toArray(new T[0])가 성능적으로 우수하다는 연구 결과가 있으므로 일반적으로 이 방식을 권장한다.
'Language > Java' 카테고리의 다른 글
[effective java] 아이템 56. 공개된 API 요소에는 항상 문서화 주석을 작성하라. (0) | 2023.07.17 |
---|---|
[effective java] 아이템 55. 옵셔널 반환은 신중히 하라. (0) | 2023.07.17 |
[effective java] 아이템 53. 가변인수는 신중히 사용하라. (0) | 2023.07.17 |
[effective java] 아이템 52. 다중정의는 신중히 사용하라. (0) | 2023.07.17 |
[effective java] 아이템 51. 메서드 시그니처를 신중히 설계하라. (0) | 2023.07.17 |