티스토리 뷰

(Effective Java) 규칙53. null 대신 빈 배열이나 컬렉션을 사용하라


null 반환의 문제..

  • Collection을 다루는 코드를 쓰다 보면 아래와 같은 경우는 어렵지 않게 만날 수 있다.

    private final List<Ball> ballList = ...;
    public Ball[] getBalls() { if (ballList.size() == 0) return null; .... 
  • 문제는 위 코드를 사용하는 클라이언트측에서 발생 할 수 있다.

  • null이 반환될 때의 처리를 추가해줘야 하는데 만약 이를 잊은 경우 오류를 유발한다. 이런 문제는 드러나지 않은 채로 몇년씩이나 잠복해있을 수 있다는 점에서 아주 위험하다.


빈 배열, 컬렉션을 반환하라

  • 문제 해결을 위해서는 빈 배열, 컬렉션을 만들어 반환해야 한다.

But..

  • 배열 할당은 피할 수 있으니 null을 반환해야 하지 않나?

    1. 해당 메서드가 성능 저하의 주범이라는 것이 밝혀지지 않는 한 성능 걱정을 하는 것은 바람직 하지 않음
    2. 길이가 0인 배열은 변경이 불가능하기 때문에 아무 문제 없이 재사용 가능함
  • 빈 배열을 반환하는 표준적인 방법은 아래와 같다.

    • 컬렉션에서 배열을 만들어 반환하는 올바른 방법
    private final List<Ball> ballList = ...;
    private static final Ball[] EMPTY_BALL_ARRAY = new Ball[0];
    public Ball[] getBalls() {
         return ballList.toArray(EMPTY_BALL_ARRAY);  
      }  
  • 보통 toArray는 반환되는 원소가 담길 배열을 스스로 할당하는데, 컬렉션이 비어 있는 경우 인자로 주어진 빈 배열을 사용한다.

  • Collection.toArray(T[])의 명세를 보면, 인자로 주어진 배열이 컬렉션의 모든 원소를 담을 정도로 큰 경우에는 해당 배열을 반환값으로 사용한다고 되어 있음

      public <T> T[] toArray(T[] a) {
              if (a.length < size)
                  // Make a new array of a's runtime type, but my contents:
                  return (T[]) Arrays.copyOf(elementData, size, a.getClass());
              System.arraycopy(elementData, 0, a, 0, size);
              if (a.length > size)
                  a[size] = null;
              return a;
          }
    • List의 size는 0이므로 System.arraycopy를 사용할 것임
      • Array.copyOf는 배열을 새로 할당하여 값을 복사하는 것임
      • System.arraycopy 는 이미 존재하는 배열에 값을 복사하는 것임
  • 마찬가지로, 컬렉션을 반환하는 경우에도 Collections.emptySet, emptyList, emptyMap 등 빈 컬렉션 객체를 반환 하도록 구현이 가능하다.


결론

null 대신에 빈 배열이나, 빈 컬렉션을 사용하자.

C에서는 ..

  • C에서는 배열의 길이와 배열이 따로 반환된다.
    • 그렇기 때문에 길이0인 배열을 할당해서 반환하더라도 아무 이득이 없다.


끝으로

이 글이 도움이 되었다면, Google 광고 한번씩 클릭 부탁 드립니다. 🙏🙏🙏

광고 클릭은 많은 힘이 됩니다!

 

반응형
댓글