Skip to content

Item 54. null이 아닌, 빈 컬렉션이나 배열을 반환하라 #52

@lain1nya

Description

@lain1nya

Chapter : 8. Methods

Item : 54. null이 아닌, 빈 컬렉션이나 배열을 반환하라

Assignee : : Lainlnya


🍑 서론

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

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

주변에서 흔히 볼 수 있는 메서드

⇒ 재고가 없다고 해서 특별히 취급할 필요가 없으며, 이 상황에서 null을 반환한다면 클라이언트는 null을 처리하는 코드를 추가로 작성해야 한다.

❗ null을 반환하는 메서드를 사용한다면 아래와 같은 방어 코드를 넣어줘야 한다.

List<Cheese> cheeses = shop.getCheeses();
if (cheeses != null && cheeeses.contains(Cheese.STILTON))
	System.out.println("좋았어, 바로 그거야");

🍑 본론

빈 컨테이너를 할당하는 데도 비용이 드니 null을 반환하는 쪽이 낫다.

반박 1. 성능 분석 결과 이 할당이 성능 저하의 주범이라고 확인되지 않는 한, 이 정도의 성능 차이는 신경 쓸 수준이 못 된다.

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

public List<Cheese> getCheeses() {
	return new ArrayList<>(cheesesInStock);
}

✅ 사용 패턴에 따라 빈 컬렉션 할당이 성능을 눈에 띄게 떨어뜨린다면 ?

⭕ 매번 똑같은 빈 불변 컬렉션을 반환하는 것 ⇒ 불변 객체는 자유롭게 공유해도 안전하기 때문이다.

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

집합이 필요하다면 Collections.emptySet을, 맵이 필요하면 Collections.emptyMap을 사용하면 된다.

하지만 사용했다면 수정 전과 후의 성능을 측정하여 실제로 성능이 개선되었는지 확인하는 것이 좋다.

배열을 쓸 때도 아래와 같이 길이가 0인 배열을 반환하면 되는데, 성능에 걱정이 된다면 길이 0짜리 배열을 미리 선언해두고 매번 빈 배열을 반환하면 된다.

private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];
public Cheese[] getCheeses() {
	return cheeseInStock.toArray(EMPTY_CHEESE_ARRAY);
}

🍑 결론

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

null을 반환하는 API는 사용하기 어렵고 오류 처리 코드도 늘어난다. 그렇다고 성능이 좋은 것도 아니다.


Referenced by

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions