본 포스트는 책 '이펙티브 자바' 에서 학습한 내용을 기반으로 작성되었습니다.
요약
자바 8부터 디폴트 메서드의 도입으로 기존의 인터페이스를 문제없이 수정할 수 있게 되었지만, 되도록이면 신중하게 디폴트 메서드를 추가하자.
디폴트 메서드
디폴트 메서드는 자바 8부터 추가된 내용으로, 기존 인터페이스에 메서드를 추가할 수 있는 새로운 방법이다. 인터페이스의 기존 구현체에서 디폴트 메서드를 재정의 하지 않아도 디폴트 구현이 자동으로 쓰이기 때문에 웬만하면 문제없이 인터페이스에 추가할 수 있다고 한다. (100%는 아님)
자바 8에서는 람다를 활용하기 위한 목적으로 핵심 컬렉션 인터페이스들에 다수의 디폴트 메서드가 추가되었음.
예시 : removeIf()
// 예시
arrayList.removeIf('람다?')
// 디폴트 메서드 안에 함수형 인터페이스를 활용해 람다를 사용할 수 있다?
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;
}
- 반복자를 이용해 순회하면서 각 원소를 인수로 넣어 프레디키트를 호출
- 프레디키드가 반환값이 true라면 반복자의 remove 메서드를 호출
- 해당 원소 제거
문제
- 디폴트 메서드 추가로 문제를 안 일으킨다는 보장이 없음
- 변경 전 인터페이스를 사용하는 클라이언트에서 문제 발생 가능성 존재
- 컴파일 에러가 발생하지 않더라도, 런타임 에러의 위험성
- 예기치 못한 충돌/API 재앙, 사용자 불편 상황 발생 가능성 존재
→ 되도록이면 기존 인터페이스에는 디폴트 메서드를 추가하지 말자.
문제 해결 방법
- 인터페이스 구현체에서 디폴트 메서드 재정의 강제
- 다른 메서드에서는 디폴트 메서드를 호출하기 전에 필요한 작업 강제
- 기존 인터페이스에 디폴트 메서드로 새 메서드를 추가하는 일은 꼭 필요한 경우가 아니면 하지 말자
- 기존 인터페이스가 아닌 새로운 인터페이스를 설계하는 경우라면 위험성 적음
인터페이스 설계 후 해야할 일들
바로 잡을 기회가 아직 남았을 때 결함을 테스트로 찾아내자
- 새로운 인터페이스인 경우 릴리스 전에 반드시 테스트를 거쳐야 함
- 인터페이스의 서로 다른 구현 케이스를 생각해 테스트 해야함
- 인터페이스를 사용하는 다양한 클라이언트도 만들어서 테스트 해야함
'Dev Language > EffectiveJava' 카테고리의 다른 글
[EffectiveJava] 이왕이면 제네릭 메서드로 만들라 (0) | 2025.01.11 |
---|---|
[EffectiveJava]이왕이면 제네릭 타입으로 만들라 (0) | 2025.01.05 |
[EffectiveJava] 로 타입(raw type)은 사용하지 말라 (4) | 2024.12.29 |
[EffectiveJava] 멤버 클래스는 되도록 static으로 만들라 (0) | 2024.12.22 |
[Effective Java] 생성자 대신 정적 팩터리 메서드를 고려하라 (0) | 2023.11.09 |