Search

Item 40. @Override 애너테이션을 일관되게 사용하라

생성일
2023/07/27 00:30
챕터
6장 - 열거 타입과 애너테이션

@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[] arqs) { Set<Biqram> 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()); } }
Java
복사
위 코드는 똑같은 소문자 2개로 구성된 Bigram 26개를 10번 반복해 Set에 추가하고 그 집합의 크기를 출력하는 코드이다. 의도한 동작은 Set에서 중복을 허용하지 않기 때문에, 26이 출력되기를 기대하지만 실제 260이 출력된다.
그 이유는 equals 메서드를 재정의(overriding) 한 것이 아니라 다중정의(overloading) 했기 때문이다. equals는 Object의 메서드로 매개변수를 Object 타입을 받는데, Bigram을 매개변수로 받기 때문에 다중정의가 되버렸다.
@Override public boolean equals(Bigram b) { return b.first == first && b.second == second; }
Java
복사
단순히 이와 같이 @Override 애노테이션을 붙인다고 해결되지는 않지만, 적어도 컴파일타임에 오류를 발생 시켜주고 잘못된 부분을 짚어주기 때문에 오동작을 막아줄 수 있다.
@Override public boolean equals(Object o) { if (!(o instanceof Bigram)) return false; Bigram b = (Bigram) o; return b.first == first && b.second == second; }
Java
복사
이러한 이유로 상위 클래스의 메서드를 재정의하려는 모든 메서드에 @Override 애노테이션을 달자.
예외적으로 상위 클래스의 추상 메서드의 경우 구체 클래스가 없다면 컴파일러에서 바로 알려주기 때문에 @Override 애노테이션을 굳이 달지 않아도 된다.
클래스를 상속 받는 경우 뿐 아니라 인터페이스를 구현하는 경우에도 @Override를 달아주는 습관을 가지는게 좋다.