티스토리 뷰
Item54에서는 null이 아닌 빈 컬렉션이나 배열을 반환하라 말한다
생각해보면 어떤 객체든 값이 없는 경우 null 반환 때리면 간단한데 왜 하지 말라는 걸까?
null 만든 사람조차 10억 달러짜리 실수라 말했기 때문이다
어떤 메서드든 null을 반환하면 클라이언트 측에서 null check가 필요하다
만약 something 객체가 인스턴스 변수로 참조 타입을 가지고 있고 그 참조를 사용하려 한다면 null check 한방 더 들어간다
if (something != null)
// 로직 수행
if (something == null)
throw new 어쩌구Exception();
null check로 콜백 지옥과 같은 형태로 뎁스가 쭉쭉 늘어나 진짜 중요한 비즈니스 로직을 가리게 될 수 있고
실수로 빠트린 경우에는 수 많은 null check 사이에서도 NPE가 터질 수 있다
그렇다면 null을 반환하지 않으려면 어째야 하는가?
책의 조언을 따라 빈 컬렉션이나 배열을 반환하자, 완벽하지는 않지만 최선의 방법이다
빈 컬렉션이나 배열을 이용해도 위험한 상황은 컬렉션 & 배열 안의 요소를 직접 다룰 때다
아래와 같이 요소를 다룰 필요가 있을 때는 이 때도 CollectionUtils.isEmpty(), Arrays.size() 등의 체크가 필요하다
list.get(0).어쩌구
array[0].저쩌구
요런 상황을 제외하고는 빈 컬렉션에는 Collections.emptyList(), new Array [0]의 형태로 최적화도 가능하다
처음 읽었을 때는 어차피 얘네도 체크가 필요한 것 아닌가 싶었다
근데 단순히 반환된 걸로 향상된 for문 돌릴 때는 요소가 없어 돌아가지 않아, NPE가 터지지 않는 문제 없는 코드임을 알았다
그럼에도 아주 많은 작업을 하는 메서드에서는 early-return으로 약간의 성능 향상을 얻을 수 있다
비어 있는 경우 빨리 끝내버리고 후행 로직을 안 타게 만들면 된다
if (CollectionUtils.isEmpty(list)) {
return;
}
// 무진장 긴 로직
마지막으로 IDE의 힘을 빌려 롬복의 @NonNull, 스프링의 @NotNull, jetbrains의 @NotNull 등을 활성화시키고
메서드의 인자 쪽에 붙여주면 null이 들어갈 수 있는 가능성이 있는 부분에서 경고를 띄워준다
settings -> compiler -> configure annotation에서 설정하면 된다
아래와 같이 null이 들어오면 안 되는 곳에 @NotNull 혹은 @NonNull 붙이라고 IDE의 경고가 뜬다
이 기능이 나쁘지 않은 것 같아 사용 중이긴 한데 단점으로 인자가 많은 경우 메서드 시그니처가 상당히 더러워진다는 점이 있다
맘에 들진 않지만 코틀린식 매개변수 나열을 하면 그나마 깔끔해진다
Optional 반환하면 되는데 왜 빈 컬렉션 반환하지라는 의문이 생길 수 있는데
그에 대답으로 아래 댓글을 소개한다
Optional 자체가 null을 대체하기 위해 만들어진 것이 아니고 상황에 따라 쓸 수 있고, 써선 안 되는 경우가 있다
Optional 남발은 안티 패턴이며 얘를 써도 값이 들었는지 비었는지 체크가 필수이기 때문에
성능도 조금 깎아먹고 값 체크는 또 해야 되는 그런 놈이다만 데이터 처리 과정에 체이닝을 할 수 있어 편하긴 하다
'Java > Effective Java' 카테고리의 다른 글
[Item56] 주석은 죄가 아니다 (0) | 2022.05.23 |
---|---|
[Item55] Optional vs Null check (2) | 2022.05.14 |
[Item53] 가변 인수 대신 컬렉션 (0) | 2022.05.07 |
[Item52] 다중정의는 타입이 다르게 (0) | 2022.05.05 |
[Item51] 설계를 신중히 (0) | 2022.05.01 |