@Override 애노테이션을 일관되게 사용하라
이전 아이템에서 애노테이션은 해당 코드에 대한 추가적인 정보를 제공하는 역할이라고 했다.
자바에는 기본적으로 제공되는 애노테이션들이 존재한다.
- @Override
- 해당 메서드가 상위 클래스의 메서드를 오버라이드하고 있음을 컴파일러에게 알림.
- 메서드 선언에만 달 수 있다.
- @Deprecated
- 더 이상 사용되지 않거나, 향후 제거될 가능성이 있는 클래스, 메서드, 필드에 붙인다.
- 종종 봤을 것이다.
- @SuppressWarning
- 컴파일러 경고를 무시하도록 하는데 사용된다.
- 이전 아이템에서 비검사 경고를 제거하는데 사용했었다.
- @SafeVarargs
- 가변 인수 제네릭 배열 생성 시 발생하는 경고를 제거하는데 사용된다.
- 제네릭 가변 인수 타입을 공부할 때 보았다. 타입 안전을 확신하면 경고를 지울 수 있다. (T… args)
- @FunctionalInterface
- 함수형 인터페이스임을 명시하는데 사용된다. 하나의 추상 메서드만을 가지는 인터페이스이다.
- 람다 표현식이나 메서드 참조를 가능하게 해준다.
이 중 제일 많이 사용하는 @Override에 대해 다뤄본다.
@Override
- 메서드 재정의를 위한 조건
- 상속 관계에서 발생.
- 접근 제어자, 리턴 타입, 매개 변수가 모두 일치해야 한다.
- 접근 제어자는 확장 가능하지만 축소는 불가능하다.
1
2
3
public boolean equals(Point p) {
return p.y == y && p.x == x;
}
- 위와 같이 재정의하면 어떻게 될까?
- 위 메서드는 equals()를 재정의한 것이 아니다. equals() 메서드를 오버로딩한 것이다.
- equals()는 Object의 메서드이다.
- 매개변수 타입이 Object인데 위에서는 Point를 받아버렸다. 오버로딩이 된 셈이다.
이런 경우를 방지하고자 애노테이션을 사용하라는 것이다. @Override 애노테이션을 달면 잘못된 부분을 컴파일러가 전부 명확히 알려준다.
따라서 상위 클래스의 메서드를 재정의하려는 모든 메서드에 @Override 애노테이션을 달아야 한다.
예외가 하나 있다. 구체 클래스에서 상위 클래스의 추상 메서드를 오버라이딩하는 경우이다. 컴파일러가 애노테이션이 없어도 추상 메서드를 구현하지 않았다는 사실을 알려준다. 따라서 달아도 되고 안달아도 된다.
물론 습관화나 통일성에 있어 모두 붙이는 것을 추구해도 좋다.
정리
@Override 애노테이션을 통해 재정의를 하려는 작성자에게 있어 일종의 실수를 방지해주는 안전 장치를 둘 수 있다.
상위 클래스의 메서드를 재정의하는 모든 메서드에 @Override 애노테이션을 일관되게 달자.