Java
[Effectiva Java][아이템40] @Override 애너테이션을 일관되게 사용하라
jun9.com
2022. 7. 4. 02:23
아래 예시는 @Override를 실수로 빼먹었을 때 발생할 수 있는 오류이다.
[코드 40-1] 영어 알파벳 2개로 구성된 문자열을 표현하는 클래스
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) {
retrun 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()); // 260. (26이 아니고...!!)
}
}
main메서드를 보면 똑같은 소문자 2개로 구성된 바이그램 26개를 10번 반복해 집합에 추가했다.
Set은 중복을 허용하지 않으므로 26이 출력될 것 같지만 260이 출력되었다.
무엇때문일까?
위 코드는 equals 메서드와 hashCode도 함께 재정의하려 한것으로 보인다.
하지만 위는 재정의(overrriding)한게 아니라 다중정의(overloading)해버렸다.
따라서 Obejct에서 상속한 equals와 별개인 equals를 정의한게 되어버려, 식별성을 구분하지 못하고 같은 소문자를 보유한 바이그랩 10개가 각각 다른 객체로 인식되어 260이 출력된 것이다.
@Override
public boolean equals(Bigram b) {
retrun b.first = first && b.second = second;
}
그러니 위와 같이 @Override 애너테이션을 반드시 달자!
IDE에서 재정의할 메서드에 @Override 애너테이션을 달지 않으면 컴파일 오류가 발생해 고칠 수 있도록 도와주고 있다