728x90
- 인터페이스에 디폴트 메서드를 선언하면, 해당 메서드를 재정의하지 않은 모든 클래스에서 디폴트 구현이 쓰이게 된다.
- 자바 8 전에는 기존 구현체를 깨뜨리지 않고 인터페이스에 메서드를 추가할 방법이 없었다.
- 인터페이스에 새로운 메서드 추가는 절대로 없다라고 가정하였으며
- 디폴트 메서드로 추가하는 길이 열렸지만 기존 구현체들과 매끄럽게 연동되리라는 보장은 없다.
- 디폴트 메서드는 구현 클래스에 대해 아무것도 모른 채 합의 없이 무작정 "삽입"될 뿐.
- 디폴트 메서드는 컴파일이 성공하더라도 기존 구현체에 런타임 오류를 일으킬 수 있다.
interface MarkerInterface {
default void hello() {
System.out.println("MarkerInterface.hello");
}
}
class SuperClass {
private void hello() {
System.out.println("SuperClass.Hello");
}
}
public class SubClass extends SuperClass implements MarkerInterface{
public static void main(String[] args) {
SubClass subClass = new SubClass();
subClass.hello();
}
}
- 위코드를 실행하면 IllegalAccessError가 발생하는데, 이는 SubClass 에서 Super 클래스의 hello 메서드에 접근하려 해서이다.
- 원래 같으면 private 라 접근이 불가능하지만 interface 를 상속받음으로써 버그같은 결과가 발생한다.
- 기타 - ConcurrentModificationException
- 런타임 에러로, 리스트나, 맵 이터레이터 순회중 컬렉션에대한 값을 변경하거나 삭제하려할때 나오는 에러이다.
public class ConcurrentModificationExceptionExample {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
for (Integer num : list) {
//list.remove(num); //ConcurrentModificationException
}
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
Integer element = iterator.next();
//list.remove(element); //ConcurrentModificationException
iterator.remove();
}
//[]
System.out.println(list);
}
}
- 삭제를 원할시 iterator 를 사용해 지우거나 일반 for 문을 이용해 인덱스로 접근하여 지우자.
- https://codechacha.com/ko/java-concurrentmodificationexception/
728x90
'공부 > 이펙티브자바' 카테고리의 다른 글
[이펙티브자바]item 23.태그 달린 클래스보다는 클래스 계층구조를 활용하라. (0) | 2023.02.06 |
---|---|
[이펙티브자바]item 22.인터페이스는 타입을 정의하는 용도로만 사용하라. (0) | 2023.02.06 |
[이펙티브자바]item 20.추상 클래스보다는 인터페이스를 우선하라. (0) | 2023.02.03 |
[이펙티브자바]item 19.상속을 고려해 설계하고 문서화하라.그러지 않았다면 상속을 금지하라. (0) | 2023.02.03 |
[이펙티브자바]item 18.상속보다는 컴포지션을 사용하라. (0) | 2023.02.02 |
댓글