도당탕탕
Item 40 : 일관적으로 OVERRIDE 어노테이션을 사용하라. 본문
@Override를 사용하지 않았을 때, 발생할 수 있는 문제 상황
package item40;
import java.util.HashSet;
import java.util.Set;
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()); // 260
}
}
위 코드에서 코드 작성자는 equals
함수를 오버라이딩 하려고 의도한 것으로 보인다. 하지만 실제로는 파라미터 타입이 Bigram
타입이므로 오버로딩이 되어 버렸다. (원래는 Object
타입의 파라미터로 선언해야 했음)이러한 실수를 방지하기 위해서 equals
함수에 @Override
어노테이션을 추가할 수 있다. 이렇게 할 경우, 해당 함수가 오버라이딩 되지 않았다는 컴파일 에러가 발생하게 된다.
Bigram.java:10: method does not override or implement a method from a supertype
@Override public boolean equals(Bigram b) { ^
그리고 아래와 같이 수정할 수 있다.
@Override
public boolean equals(Object o) {
if (!(o instanceof Bigram))
return false;
Bigram b = (Bigram) o;
return b.first == first && b.second == second;
}
@Override 사용해야 하는 이유
- 위의 예에서처럼, 정확히 오버라이딩 했는지 확인가능하다.
- 대부분의 IDE에서는 오버라이딩된 함수에 대해서 @Override가 사용되었는지 체크를 한다. 만약 오버라이딩된 함수에 @Override가 사용되지 않았으면, Wanring을 발생시킨다. IDE에서 발생하는 Warning을 제거하기 위해서, @Override를 사용할 필요가 있다.
정리
슈퍼타입 선언에 있는 함수를 오버라이딩하는 모든 함수에 대해서, @Override를 사용하면, 컴파일러가 적절하게 오버라이딩이 되었는지 알려준다. 하지만 한 가지 예외가 있다. 구체 클래스(concrete class)에서 추상 클래스를 상속한 경우, 오버라이딩 할 함수에 @Override를 반드시 붙일 필요는 없다. 왜냐하면 컴파일러가 강제로 구현하도록 강제해주기 때문이다. (어노테이션을 사용해도 괜찮다.)
'JAVA' 카테고리의 다른 글
Item42 : 익명 클래스 보다 Lambda를 선호하라. (0) | 2023.01.02 |
---|---|
Item41 : 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라 (0) | 2023.01.02 |
Item39 : 명명 패턴보다 애너테이션을 사용하라 (0) | 2022.12.30 |
Item38 : 인터페이스를 사용해서 확장성있는 ENUM을 재현하라. (0) | 2022.12.29 |
Item37: ordinal 인덱싱 대신 EnumMap을 사용하라 (0) | 2022.12.29 |
Comments