티스토리 뷰

핵심 정리

- 기존 인터페이스에 디폴트 메서드 구현을 추가하는 것은 위험한 일이다.

  - 디폴트 메서드는 구현 클래스에 대해 아무것도 모른 채 합의 없이 무작정 “삽입”될 뿐이다.

  - ex) 자바 8 Collection 인터페이스의 removeIf() 메서드를 재정의하지 않은 아파치의 SynchronizedCollection

  - SynchronizedCollection 인스턴스에서 removeIf()를 호출할 경우 ConcurrentModificationException이 발생하거나 다른 예기치 못한 결과로 이어질 수 있다

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;
}

- 디폴트 메서드는 기존 구현체에 런타임 오류를 일으킬 수 있다.

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();
	}
}

- 인터페이스를 설계할 때는 세심한 주의를 기울여야 한다.

  - 서로 다른 방식으로 최소한 세 가지는 구현을 해보자.

 

ConcurrentModificationException

- 현재 바뀌면 안되는 것을 수정할 때 발생하는 예외

- 멀티 스레드가 아니라 싱글 스레드 상황에서도 발생할 수 있다

  - ex) fail-fast 이터레이터를 사용해 콜렉션을 순회하는 중에 콜렉션을 변경하는 경우

public class FailFast {
	public static void main(String[] args) {
		List<Integer> numbers = new ArrayList<>();
		numbers.add(1);
		numbers.add(2);
		numbers.add(3);
		numbers.add(4);
		numbers.add(5);

		// 이터레이터로 컬렉션을 순회하는 중에 Collection의 remove를 사용한다면...
		for (Integer number : numbers) {
			if (number == 3) {
				numbers.remove(number);
			}
		}
	}
}

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/07   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함