Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

전공공부

[아이템 54] null이 아닌, 빈 컬렉션이나 배열을 반환하라 본문

Study/Java

[아이템 54] null이 아닌, 빈 컬렉션이나 배열을 반환하라

monitor 2023. 6. 20. 21:40

컬랙션이 비었을 때 null을 반환하는 메서드를 보자

 

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

/**
 * @return 매장 안의 모든 치즈 목록을 반환한다.
 * 	단, 재고가 하나도 없다면 null을 반환한다.
 */
public List<Cheese> getCheeses() {
	return cheesesInStock.isEmtpy() ? null
		: new ArrayList<>(cheesesInStock);
}

 

해당 코드의 문제점은 클라이언트가 null 상황을 처리하는 코드를 추가로 작성해야 한다.

 

List<Cheese> cheeses = shop.getCheeses();
if(cheeses != null && cheeses.contains(Cheese.STILTON))
	System.out.println("Null Pointer Exception 방지 ")

이런식으로 반환하면 클라이언트에서 방어 코드를 만들지 않는다면 오류를 발생 시킬 수 있다. 

 

그런데, 빈 컨테이너를 사용하는 것 조차 비용이 드니 null을 사용하는게 좋지 않나 싶을 수 있다.

 

하지만, 이와 같은 주장은 아래의 이유로 반박이 가능하다.

 

1. 성능 저하의 주범이라고 확인되지 않는 한 이 정도의 성능차이는 미미하다.

2. 빈 컬렉션과 배열은 굳이 새로 할당하지 않고도 쓸 수 있다.

 

빈 컬렉션과 배열을 굳이 새로 할당하지 않고도 쓸 수 있는 예시가 아래의 코드이다.

 

 

1. 컬렉션의 경우

 

public List<Cheese> getCheeses() {
    return cheesesInStock.isEmpty() ? 
    Collections.emptyList() : new ArrayList<>(cheesesInStock);
}

Collections 클래스에서 제공하는 emptyList() 메서드로 빈 리스트 객체를 반환 할 수 있고 실제 리스트가 존재하면 새로 할당하여 복사된 객체를 리턴한다.

 

Collections의 static final 객체를 반환해준다.

2. 배열의 경우

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

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

 

Cheese 객체로 구성된 리스트를 배열로 바꿔서 리턴 할 때 위와 같이 구성하면 toArray 메서드가 chessesInStock을 배열의 형태로 만들어 구성한다. 만일 빈 리스트 였다면 new Cheese[0] 배열을 리턴한다.

 

이것을 또 최적화 하면 아래와 같이 새로 할당하지 않고 계속 쓸 수 있다.

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

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

 

하지만, 성능을 개선할 목적이라면 위와 같이 넘기는 배열을 미리 할당하는 것은 추천하지 않는다고 한다. 오히려 성능이 떨어진다는 연구결과가 존재한다고 한다.

 

return cheesesInStock.toArray(new Cheese[cheesesInStock.size()]); //이런식의 할당은 성능이 나빠진다.

 

결론


null이 아닌 빈 배열이나 빈 컬렉션을 반환해라.