티스토리 뷰
반응형
디폴트 메서드의 도입
- 자바8부터는 기존 인터페이스에 메서드를 추가할 수 있도록 디폴트 메서드를 도입.
but 디폴트 메서드를 재정의하지 않은 모든 클래스에서 디폴트 구현이 쓰이게 되므로 모든 기존 구현체들과 매끄럽게 연동되리라는 보장을 할 수 없음
- 자바8에서는 핵심 컬렉션 인터페이스들에 다수의 디폴트 메서드가 추가됨 → 람다 활용 위해
추가된 메서드들은 품질이 높고 범용적이어서 대부분 상황에서 잘 작동
but 모든 상황에서 불변식을 해치지 않는 디폴트 메서드를 작성하긴 어렵다.
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
ex) Collection 인터페이스에 추가된 removeIf 메서드는 아파치의 SynchronizedCollection 클래스와 잘 어우러지지 않음.
SynchronizedCollection 클래스 : 모든 메서드에서 주어진 락 객체로 동기화한후에 내부 컬렉션 객체에 기능을 위임하는 래퍼클래스
이 클래스에서는 removeIf 메서드를 재정의하지 않고 있다.
removeIf 구현은 동기화에 관해 모르기때문에 락 객체를 사용할 수가 없다.
→ ConcurrentModificationException 발생 or 예기치 못한 결과
구현한 인터페이스의 디폴트 메서드를 재정의하고, 다른 메서드에서는 디폴트 메서드를 호출하기 전에 필요한 작업을 수행하도록 함. but 자바 플랫폼에 속하지 않는 것들 중 일부는 여전히 수정이 안됨.
디폴트 메서드를 작성할때 주의할점
- 디폴트 메서드는 컴파일에 성공할 수는 있어도 기존 구현체에 런타임 오류를 일으킬 수 있음.
- 그래서 반드시 필요한 경우가 아니면 피해야한다.
기존 인터페이스에 새로운 디폴트 메서드를 추가할때는 세심한 주의를 필요 - 새로운 인터페이스라면 릴리스 전에 테스트를 거쳐야함
- 서로 다른 방식으로 최소한 세가지로 구현해보자
- 각 인터페이스의 인스턴스를 다양한 용도로 활용되게끔 여러개를 만들어보자
- 릴리스 후에 결함을 수정할 가능성에 기대서는 안됨
반응형
'Java > Effective Java' 카테고리의 다른 글
[Effective Java] 23.태그 달린 클래스보다는 클래스 계층구조를 활용하라 (0) | 2022.03.17 |
---|---|
[Effective Java] 22.인터페이스는 타입을 정의하는 용도로만 사용하라 (0) | 2022.03.17 |
[Effective Java] 20.추상 클래스보다는 인터페이스를 우선하라 (0) | 2022.03.16 |
[Effective Java] 19.상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라 (0) | 2022.03.16 |
[Effective Java] 18.상속보다는 컴포지션을 사용하라 (0) | 2022.03.12 |
댓글