티스토리 뷰

728x90
반응형

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


  • 클라이언트에서 컬렉션을 반환하는 메서드나, 배열을 반환하는 메서드를 호출했을 경우 만약 null을 반환한다면 클라이언트쪽에서 null체크를 감지하는 방어 코드를 항상 작성해주어야 합니다.

 

💡 예제 코드

  • 아래 예제에서 getMembers 메서드는 컬렉션이 비어있는 경우 null을 반환하는 메서드입니다. 이 메서드가 어떤 문제를 발생시킬 수 있을까요?
  • 답은 main 메서드에서 getMembers 메서드를 호출할 때 null 검사를 하는 방어 로직을 작성해야 합니다. 이처럼 방어 코드가 작성되지 않았을 경우 NPE가 발생하게 됩니다.
public class Member {

    private static List<Member> members = new ArrayList<>();
    private final String name;

    public Member(String name) {
        this.name = name;
    }

    public static void add(Member member) {
        members.add(member);
    }

    public static List<Member> getMembers() {
        if (members.isEmpty()) {
            return null;
        }
        return new ArrayList<>(members);
    }
}


public class Example {

    public static void main(String[] args) {

        List<Member> members = Member.getMembers();

        if (Objects.nonNull(members)) { // null 체크
            members.forEach(System.out::println);
        }
    }
}

 

💡 해결 방법 1)

  • getMembers 메서드에서 컬렉션이 비어있는 경우 새로운 컬렉션을 반환하는 것입니다. 하지만 새로운 컬렉션을 생성해서 반환하는 것은 성능 저하의 우려가 있다고 하는데 신경 쓸 수준이 아니라고 합니다. 
public static List<Member> getMembers() {
    if (members.isEmpty()) {
        return new ArrayList<>();
    }
    return new ArrayList<>(members);
}

public static void main(String[] args) {
    List<Member> members = Member.getMembers();
    members.forEach(System.out::println);

}

 

💡 해결 방법 2)

  • 그래도 새로운 컬렉션을 생성하여 반환할 때 비용이 문제가 된다면 빈 불변 컬렉션을 반환할 수 있습니다.
  • Collections라는 컬렉션 유틸 클래스에서 제공하는 emptyList, emptySet, emptyMap 메서드를 사용할 수 있는데, 이는 정말 성능 최적화가 필요한 경우에만 사용하도록 해야합니다.
public static List<Member> getMembers() {
    if (members.isEmpty()) {
        return Collections.emptyList();
    }
    return new ArrayList<>(members);
}

public static void main(String[] args) {
    List<Member> members = Member.getMembers();
    members.forEach(System.out::println);
}

 

💡 참고: 빈 배열 반환하기

  • 컬렉션이 아닌 배열을 사용하는 경우에도 컬렉션과 동일합니다. null이 아닌 배열을 반환하면 됩니다.
public class Member {

    private static Member[] members = new Member[16];

    public static Member[] getMembers() {
        if (members.length == 0) {
            return new Member[0];
        }
        return members;
    }
}

 

 

 

 

 

728x90
반응형