■ 인터페이스 디폴트 메서드

  • 모든 상황에서 불변식을 해치지 않는 디폴트 메서드를 작성하기는 어렵다.
  • 디폴트 메서드는 기존 구현체에 런타임 오류를 일으킬 수 있다.
  • 인터페이스를 설계 할 때는 세심한 주의를 기울여야 한다.

 

■ 자바 8의 Collection 인터페이스에 추가된 디폴트 메서드

자바 8에서 추가된 Collection 인터페이스의 removeIf() 메서드는 Predicate의 결과에 따라 원소를 제거하는 함수이다. 범용적으로 구현되어 있지만 모든 Collection 구현체와 어우러지는 것은 아니다. 

default boolean removeIf(Predicate<? super E> filter) {
  Objects.requireNonNull(filter);
  boolean result = false;
  for (Iterator<E> it = iterator(); it.hasNext();) {
    if (filter.test(it.next())) {
      it.remove();
      result = true;
    }
  }
  return result;
}

 

대표적인 예시가 아파치 SynchronizedCollection이다. 4.4이전 버전에서는 removeIf가 재정의되있지 않아 default 메서드를 실행한다. 이때 ConcurrentModificationException이 발생할 수 있다. SynchronizedCollection은 모든 메서드에 주어진락 객체로 동기화한 후 내부 컬렉션 객체에 기능을 위임하는 래퍼 클래스이다. removeIf를 재정의 하지 않았으므로 락 객체를 사용할 수 없다.

 

SynchronizedCollection에서 removeIf()메서드는 4.4버전 부터 동기적으로 override 되도록 수정되었다.

 

■ 정리

  • 기존 메서드를 제거하거나 수정하는 용도가 아니다.
  • 디폴트 메서드로인해 기존 클라이언트를 망가뜨릴 수 있다.
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기