null을 반환하지 말자
다음 코드와 같이 컬렉션이 비어있으면 null을 반환하는 경우가 있습니다.
위 코드와 같이 null을 반환하는 경우, 클라이언트는 다음 코드와 같이 null 체크 후 적절히 처리하는 코드를 추가해야 합니다.
특히, getCheeses() 메서드와 같이 컬렉션이나 배열과 같은 컨테이너가 비었을 때 null을 반환할 경우 클라이언트는 항시 위와 같이 방어 코드를 넣어줘야 합니다.
클라이언트에서 방어 코드를 누락하면 오류가 발생할 수 있으며, 객체가 0개일 가능성이 희박한 상황에서는 엣지 케이스가 발생할 때까지 코드에서 오류를 인지하기 어려울 수 있습니다.
빈 컨테이너를 반환하는 것보다 null을 반환하는 것이 더 낫지 않나?
소제목처럼 때로는 빈 컨테이너를 할당하는 행위도 비용이 드니 null을 반환하는 쪽이 낫다고 주장하는 개발자도 있습니다.하지만 위 주장은 두 가지 면에서 잘못된 주장입니다.
- 성능에 극도로 민감하지 않는 한 개발자는 빠른 프로그램보다는 좋은 프로그램을 개발하는 것을 추구해야 함
- 빈 컬렉션과 배열은 굳이 새로 할당하지 않고도 반환할 수 있음
1. 성능에 극도로 민감하지 않은 한 개발자는 빠른 프로그램보다는 좋은 프로그램을 개발하는 것을 추구해야 함
성능 분석 결과 빈 컨테이너를 할당하는 것이 성능 저하의 주범이라고 확인되지 않은 한 이 정도의 성능 차이는 미미하며 성능에 극도로 민감하지 않는 한 개발자는 빠른 프로그램보다는 좋은 프로그램을 개발하는 것을 추구해야 합니다.
2. 빈 컬렉션과 배열은 굳이 새로 할당하지 않고도 반환할 수 있음
빈 컬렉션과 배열은 굳이 새로 할당하지 않고도 반환이 가능하며 다음 코드는 빈 컨테이너를 반환하는 전형적인 코드입니다.
매번 똑같은 빈 `불변` 컬렉션을 반환하자
가능성은 희박하지만 사용 패턴에 따라 빈 컬렉션 할당이 성능 저하를 유발할 수 있습니다.
아이템 17에서 다루었다시피 불변 객체는 자유롭게 공유해도 안전하기 때문에 위 문제의 해법은 매번 똑같은 빈 `불변` 컬렉션을 반환하는 것입니다.
단 위 코드처럼 빈 컬렉션을 반환하는 작업도 `최적화`에 해당하니 꼭 필요할 때만 사용하는 것을 권장합니다.
빈 컬렉션을 불변 객체로 처리하는 것은 추가적인 리소스와 연산을 필요로 할 수 있으며 이러한 최적화를 모든 상황에서 적용하면 오히려 불필요한 비용이 발생할 수 있습니다.
배열을 쓸 때도 null을 반환하지 말자
다음 코드처럼 배열을 반환하는 메서드에서 빈 배열이라 할지라도 null을 반환하지 말고 길이가 0인 배열을 반환하는 것을 권장합니다.
- 보통은 단순히 정확한 길이의 배열을 반환하기만 하면 됨
- 그 길이가 0일 수도 있을 뿐
위 방식이 성능을 떨어뜨릴 것 같다면 길이 0짜리 배열을 미리 선언한 뒤 매번 해당 배열을 반환하면 됩니다.
길이 0인 배열은 모두 불변이기 때문입니다.
코드 부연 설명
- 위 버전의 getCheesesByArray()는 항상 EMPTY_CHEESE_ARRAY를 인수로 넘겨 toArray를 호출
- 따라서 cheesesInStock이 비었을 때면 언제나 EMPTY_CHEESE_ARRAY를 반환
주의: 배열을 미리 할당하는 것은 오히려 성능 저하를 유발할 수 있다는 연구 결과가 있기 때문에 단순 성능을 개선할 목적이라면 toArrray에 넘기는 배열을 미리 할당하는 것을 권장하지 않음
실제로 다음 코드를 보면 배열을 미리 할당하는 것이 그렇지 않은 경우에 비해 13배 느린 것을 확인할 수 있습니다.
- 13ms vs 1ms이기 때문에 절대적인 수치면에서는 미미하지만 성능 차이가 난다는 것은 자명
정리
null을 반환하는 API는 클라이언트 입장에서 사용하기 어렵고 오류 처리 코드도 늘어나기 때문에 반드시 null이 아닌 빈 배열 혹은 컬렉션을 반환하는 것을 권장합니다.
성능에 극도로 민감하지 않은 한 개발자는 빠른 프로그램보다는 좋은 프로그램을 개발하는 것을 추구해야 합니다!
'JAVA > Effective Java' 카테고리의 다른 글
[아이템 56] 공개된 API 요소에는 항상 문서화 주석을 작성하라 (0) | 2024.03.13 |
---|---|
[아이템 55] 옵셔널 반환은 신중히 하라 (0) | 2024.03.12 |
[아이템 53] 가변인수는 신중히 사용하라 (0) | 2024.03.11 |
[아이템 52] 다중정의는 신중히 사용하라 (1) | 2024.03.10 |
[아이템 51] 메서드 시그니처를 신중히 설계하라 (0) | 2024.03.09 |