Java/Effective Java 3E

[이펙티브자바 3판] ITEM40. @Override 애너테이션을 일관되게 사용하라

잭피 2020. 11. 29. 19:05

이번장의 핵심은...

재정의한 모든 메서드에 @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”로 메일을 보내주시면, 바로 삭제하도록 하겠습니다.