이펙티브 자바, 쉽게 정리하기 - item 40.
@Override
애너테이션을 일관되게 사용하라
@Override
가 없을 때 하기 쉬운 실수
public class Item40Test {
static 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;
}
}
@Test
public void bigramTest() {
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));
}
}
Assertions.assertEquals(26, s.size()); // 실제 값 260
}
}
bigramTest()
가 원한 결과는s.size()
가26
인 것이지만 실제로는260
이 나왔다.equals()
에@Override
애너테이션을 붙이지 않아서 생긴 실수가 있다.Object
에서 상속받는equals()
는 원래Object
타입의 파라미터를 받는데,Bigram
의 파라미터를 받고 있다.- 그래서
Set
에서 비교에 사용되는equals()
가 제대로 정의되지 않고, 오직 객체 주소의 동치만 비교하는 기본Object
의equals()
가 쓰이고 있던 것이다. - 실제 오버라이딩(재정의)된 것이 아니라 오버로딩을 하고 있는 것이다.
실수 고치기
@Override
public boolean equals(Object o) {
if(!(o instanceof Bigram)) {
return false;
}
Bigram b = (Bigram) o;
return b.first == first && b.second == second;
}
- 위와 같이
@Override
애너테이션을 달면, 실제로 상속받은 메서드가 아니면 에러를 내주기 때문에 실수할 확률이 적어진다. @Override
를 통해 시그니쳐가 올바른지 다시한번 확인하자.
핵심 정리
- 재정의한 모든 메서드에
@Override
애너테이션을 달아 실수를 방지하자. - 단, 구체 클래스에서 상위 클래스의 추상 메서드를 재정의한 경우엔 이 애너테이션을 달지 않아도 된다.
반응형
'Java > 이펙티브 자바' 카테고리의 다른 글
이펙티브 자바, 쉽게 정리하기 - item 42. 익명 클래스보다는 람다를 사용하라 (0) | 2022.06.13 |
---|---|
이펙티브 자바, 쉽게 정리하기 - item 41. 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라 (0) | 2022.05.24 |
이펙티브 자바, 쉽게 정리하기 - item 39. 명명 패턴보다 애너테이션을 사용하라 (0) | 2022.05.24 |
이펙티브 자바, 쉽게 정리하기 - item 38. 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라 (0) | 2022.02.24 |
이펙티브 자바, 쉽게 정리하기 - item 37. ordinal 인덱싱 대신 EnumMap을 사용하라 (0) | 2022.02.24 |