[이펙티브자바 3판] ITEM40. @Override 애너테이션을 일관되게 사용하라
이번장의 핵심은...
재정의한 모든 메서드에 @Override 애너테이션을 의식적으로 달면
여러분이 실수했을 때 컴파일러가 바로 알려줄 것이다
예외는 한 가지인데, 단다고 해서 해로울 것도 없다
@Override
상위 메서드 재정의
이 애너테이션을 일관되게 사용하면 여러 가지 악명 높은 버그를 예방해줌
Bigram Class 예제
// 코드 40-1 영어 알파벳 2개로 구성된 문자열(바이그램)을 표현하는 클래스 - 버그를 찾아보자. (246쪽)
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());
}
}
main 메서드 : 똑같은 소문자 2개로 구성된 바이그램 26개를 10번 반복해 집합에 추가한 다음, 그 집합의 크기를 출력 (a/a)(b/b) ... (z/z)
Set이라 중복을 허용하지 않아 26이 출력될 거 같지만, 실제 260이 출력
equals를 overriding 한 게 아니라, overloading(다중정의)를 해버림
Object의 equals를 재정의하려면 매개변수 타입을 Object로 했어야함
따라서 매개변수가 Bigram으로 별개인 equals를 새로 정의한 꼴임
Object의 equals는 == 연산자와 똑같이 객체 식별성만 확인
따라서 같은 소문자를 소유한 바이그램 10개 각각 서로 다른 객체로 인식되어 260이 출력됨
아래처럼 변경하면, 컴파일 오류가 발생
@Override
public boolean equals(Bigram b) {
return b.first == first && b.second == second;
}
-> 수정
@Override public boolean equals(Object o) {
if (!(o instanceof Bigram2))
return false;
Bigram2 b = (Bigram2) o;
return b.first == first && b.second == second;
}
즉, 잘못된 부분을 명확히 알려주므로 곧장 올바르게 수정이 가능
상위 클래스의 메서드를 재정의하려는 모든 메서드에 @Override 애너테이션을 달자
예외는 한 가지 뿐이다
구체 클래스에서 상위 클래스의 추상 메서드를 재정의할 때는 굳이 @Override를 달지 않아도 된다
컴파일러가 알려준다
물론 재정의 메서드 모두에 @Override를 일괄로 붙여주는게 Best
이 글은 “이펙티브 자바 3판” 책 내용을 정리한 글입니다.
만약 저작권 관련 문제가 있다면 “shk3029@kakao.com”로 메일을 보내주시면, 바로 삭제하도록 하겠습니다.