핵심 내용
이 아이템을 정리를 해야 하나? 싶을 정도로 당연한 말이다. 오버라이딩을 할 경우, @Override를 항상 붙혀 디버깅이 쉽도록 하자.
@Override를 일관되게 사용해야 하는 이유
public class Bigram {
private final char first;
private final char second;
public Bigram(char first, char second) {
this.first = first;
this.second = second;
}
public boolean equals(Bigram b) {
return b.first == first && b.second == second;
}
public int hashCode() {
return 31 * first + second;
}
public static void main(String[] args) {
Set<Bigram> s = new HashSet<>();
for (int i = 0; i < 10; i++)
for (char ch = 'a'; ch <= 'z'; ch++)
s.add(new Bigram(ch, ch));
System.out.println(s.size());
}
}
위 코드는 26이 아닌 260을 출력한다.
그 원인은 equals 메소드를 오버라이딩이 아닌 다중정의하였기 때문이다. 수정하도록 하자.
@Override public boolean equals(Object o) {
if (!(o instanceof Bigram2))
return false;
Bigram2 b = (Bigram2) o;
return b.first == first && b.second == second;
}
@Override를 달지 않게 되면 equals에 문제가 있음에도 컴파일 성공하게 된다. 그러므로 꼭 달도록 하자.
예외 사항
: 구체 클래스에서 상위 클래스의 메소드를 재정의할 때
구체 클래스인데 구현하지 않은 추상 메소드가 남아 있다면 컴파일러가 자동으로 알려주므로 달지 않아도 된다.
인터페이스와 @Override
디폴트 메소드를 지원하기 시작하면서, 인터페이스 메소드를 구현한 메소드에도 @Override를 다는 습관을 들이면 시그니처가 올바른지 재차 확인할 수 있다.
'Language > Java' 카테고리의 다른 글
[effective java] 아이템 42. 익명 클래스보다는 람다를 사용하라. (0) | 2023.07.02 |
---|---|
[effective java] 아이템 41. 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라. (0) | 2023.07.02 |
[effective java] 아이템 39. 명명 패턴보다 애너테이션을 사용하라. (0) | 2023.07.02 |
[effective java] 아이템 38. 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라. (0) | 2023.07.02 |
[effective java] 아이템 37. ordinal 인덱싱 대신 EnumMap을 사용하라. (0) | 2023.07.02 |