@Override
가 바로 애너테이션. 애너테이션은 @
로 시작하며, 클래스, 인터페이스, 필드, 메서드 등에 붙여서 사용할 수 있음@Override
는 example()
이 추상 메서드를 구현하거나, 상위 클래스의 메서드를 오버라이딩한 메서드라는 것을 컴파일러에게 알려주는 역할@Override
는 메서드 앞에만 붙일 수 있는 애너테이션으로, 선언한 메서드가 상위 클래스의 메서드를 오버라이딩하거나 추상 메서드를 구현하는 메서드라는 것을 컴파일러에게 알려주는 역할을 수행class SuperClass {
public void example() {
System.out.println("example() of SuperClass");
}
}
class SubClass extends SuperClass {
@Override
public void example() {
System.out.println("example() of SubClass");
}
}
SuperClass의 example()
를 SubClass에서 오버라이딩할 때, @Override
를 붙여주면 컴파일러는 SubClass의 example()
이 상위 클래스의 메서드를 오버라이딩한 것으로 간주됨.
@Override
를 발견하면 @Override
가 붙은 메서드와 동일한 이름을 가진 메서드가 상위 클래스(또는 인터페이스)에 존재하는지 검사함.@Override
가 붙어있는 메서드명과 동일한 이름의 메서드를 찾을 수 없다면 컴파일러가 컴파일 에러를 발생시킴상위 클래스에 오버라이딩 메서드와 동일한 이름의 메서드가 존재하는지 확인해야하는 이유
@Override
를 붙이지 않으면 컴파일러는 example()
이라는 새로운 메서드를 정의하는 것으로 간주하고 에러를 발생시키지 않음@Override
를 사용하면 example()
이 오버라이딩 메서드라는 것을 컴파일러가 인지하고 상위클래스에 example()
이 존재하는지 확인하기 때문에 이러한 상황을 방지할 수 있음@Deprecated
: 기존에 사용하던 기술이 다른 기술로 대체되어 기존 기술을 적용한 코드를 더 이상 사용하지 않도록 유도하는 경우에 사용애너테이션 | 설명 |
---|---|
@SupressWarnings("all") | 모든 경고를 억제 |
@SupressWarnings("deprecation") | Deprecated 메서드를 사용한 경우에 발생하는 경고를 억제 |
@SupressWarnings("fallthrough") | switch문에서 break 구문이 없을 때 발생하는 경고를 억제 |
@SupressWarnings("finally") | finally와 관련된 경고를 억제 |
@SupressWarnings("null") | null과 관련된 경고를 억제 |
@SupressWarnings("unchecked") | 검증되지 않은 연사자와 관련된 경고를 억제 |
@SupressWarnings("unused") | 사용하지 않는 코드와 관련된 경고를 억제 |
중괄호에 여러 개의 경고 유형을 나열함으로써 여러 개의 경로를 한꺼번에 묵인하게 할 수 있음
@SuppressWarnings({"deprecation", "unused", "null"})
@FunctionalInterface
public interface ExampleInterface {
public abstract void example(); // 단 하나의 추상 메서드
}
대상 타입 | 적용범위 |
---|---|
ANNOTATION_TYPE | 애너테이션 |
CONSTRUCTOR | 생성자 |
FIELD | 필드(멤머변수, 열거형 상수) |
LOCAL_VARIABLE | 지역변수 |
METHOD | 메서드 |
PACKAGE | 패키지 |
PARAMETER | 매개변수 |
TYPE | 타입(클래스, 인터페이스, 열거형) |
TYPE_PARAMETER | 타입 매개변수 |
TYPE_USE | 타입이 사용되는 모든 대상 |
import static java.lang.annotation.ElementType.*;
//import문을 이용하여 ElementType.TYPE 대신 TYPE과 같이 간단히 작성할 수 있습니다.
@Target({FIELD, TYPE, TYPE_USE}) // 적용대상이 FIELD, TYPE
public @interface CustomAnnotation { } // CustomAnnotation을 정의
@CustomAnnotation // 적용대상이 TYPE인 경우
class Main {
@CustomAnnotation // 적용대상이 FIELD인 경우
int i;
}
@Override
와 @SupressWarnings
를 제외하고는 모두 @Documented
가 적용되어 있음@Documneted
@Target(ElementType.Type)
public @interface CustomAnnotation { }
@Inherited
애너테이션을 상위 클래스에 붙이면 하위 클래스도 상위 클래스에 붙은 애너테이션들이 동일하게 적용됨@Inherited // @SuperAnnotation이 하위 클래스까지 적용
@interface SuperAnnotation{ }
@SuperAnnotation
class Super { }
class Sub extends Super{ } // Sub에 애너테이션이 붙은 것으로 인식
Super
상위 클래스로부터 확장된 Sub
하위 클래스는 상위 클래스와 동일하게 @SuperAnnotation에 정의된 내용들을 적용받게 됨
유지정책 | 설명 |
---|---|
SOURCE | 소스파일에 존재, 클래스 파일에는 존재하지 않음 |
CLASS | 클래스 파일에 존재, 실행시에 사용불가, 기본값 |
RUNTIME | 클래스 파일에 존재, 실행시에 사용가능 |
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
//오버라이딩이 제대로 되었는지 컴파일러가 확인하는 용도
//클래스 파일에 남길 필요 없이 컴파일시에만 확인하고 사라짐
public @interface Override(){ }
Override
애너테이션은 컴파일러가 사용하면 끝나기 때문에 실행 시에는 더이상 사용되지 않음을 의미
@interface Works { // 여러개의 Work애너테이션을 담을 컨테이너 애너테이션 Works
Work[] value();
}
@Repeatable(Works.class) // 컨테이너 애너테이션 지정
@interface Work {
String value();
}
@Repeatable
애너테이션은 일반적인 애너테이션과 달리 같은 이름의 애너테이션이 여러번 적용될 수 있기 때문에, 이 애너테이션을 하나로 묶어주는 애너테이션도 별도로 작성해야함.
@interface 애너테이션명 { // 인터페이스 앞에 @기호만 붙이면 애너테이션을 정의할 수 있습니다.
타입 요소명(); // 애너테이션 요소를 선언
}
애너테이션은 java.lang.annotation 인터페이스를 상속받기 때문에 다른 클래스나 인터페이스를 상속받 수 없음