136p. 디폴트 메서드는 구현 클래스에 대해 아무것도 모른 채 합의 없이 무작정 ‘삽입’될 뿐이다.
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;
}
Collection
를 구현하는 (동기화를 제공하는) SynchronizedCollection
에서 디폴트 메서드 removeIf
가 제대로 동작하지 않는다.Concurrentmodificationexception
발생할 수 있다. 한 스레드가 어떤 Collection을 반복자(iterator)를 이용하여 순회하고 있을때, 다른 한스레드가 해당 Collection에 접근하여 변경을 시도하는 경우이다. 하지만 꼭 멀티스레드 환경에서만 발생 하는것은 아니다. 싱글 스레드 환경에서도 발생할 수 있는데, 위와 같이 어떤 Collection을 순회하고 있는 반복문 안에서, 순회되고 ****있는 Collection에 대한 변경이 시도 될 때 또한 해당 Exception이 발생 하게 된다.138p. 디폴트 메서드는 (컴파일에 성공하더라도) 기존 구현체에 런타임 오류를 일으킬 수 있다. 흔한 일은 아니지만, 나에게는 일어나지 않으리라는 보장도 없다.
Allow default methods to override Object's methods
상속과 구현의 작동에 적용되는 규칙
Rule #1: Classes win over interfaces. If a class in the superclass
chain has a declaration for the method (concrete or abstract), you're
done, and defaults are irrelevant.
Rule #2: More specific interfaces win over less specific ones (where
specificity means "subtyping"). A default from List wins over a default
from Collection, regardless of where or how or how many times List and
Collection enter the inheritance graph.
public interface MarkerInterface {
default void hello() {
System.out.println("hello interface");
}
}
public class SuperClass {
private void hello() {
System.out.println("hello class");
}
}
public class SubClass extends SuperClass implements MarkerInterface {
public static void main(String[] args) {
SubClass subClass = new SubClass();
subClass.hello();
}
}
SubClass
는 클래스 SuperClass
상속받는다.SubClass
는 인터페이스 MarkerInterface
를 구현한다.subClass.hello()
의 hello()
는 어떤 메서드일까? → SuperClass 의 hello()
→ IllegalAccessError
발생