■ 인터페이스 디폴트 메서드
- 모든 상황에서 불변식을 해치지 않는 디폴트 메서드를 작성하기는 어렵다.
- 디폴트 메서드는 기존 구현체에 런타임 오류를 일으킬 수 있다.
- 인터페이스를 설계 할 때는 세심한 주의를 기울여야 한다.
■ 자바 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 되도록 수정되었다.
■ 정리
- 기존 메서드를 제거하거나 수정하는 용도가 아니다.
- 디폴트 메서드로인해 기존 클라이언트를 망가뜨릴 수 있다.
'Effective Java' 카테고리의 다른 글
[Effective Java] 아이템23 태그 달린 클래스보다는 클래스 계층구조를 활용하라 (0) | 2021.03.01 |
---|---|
[Effective Java] 아이템22 인터페이스는 타입을 정의하는 용도로만 사용하라 (2) | 2021.03.01 |
[Effective Java] 아이템20 추상 클래스보다는 인터페이스를 우선하라 (0) | 2021.02.24 |
[Effective Java] 아이템19 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라 (0) | 2021.02.23 |
[Effective Java] 아이템18 상속보다는 컴포지션을 사용하라 (0) | 2021.02.21 |
최근댓글