애너테이션은 소스 코드가 컴파일되거나 실행될 때에 컴퓨터에게 필요한 정보를 전달해주는 문법 요소이다.
public class ExampleClass implements ExampleInterface {
@Override
public void example() {
}
}
여기에서 보이는 @Override가 바로 애너테이션이다.
@Override는 컴파일러에게 “컴파일러야, 이 메서드는 상위 클래스의 메서드를 오버라이딩하거나 추상 메서드를 구현하는 메서드인데, 만약에 내가 실수해서 오버라이딩 및 구현이 잘 안되면 에러를 발생시켜서 나에게 알려줄래?”라고 부탁하는것.
class SuperClass {
public void example() {
System.out.println("example() of SuperClass");
}
}
class SubClass extends SuperClass {
@Override // 부모클래스의 example()메소드를 자식클래스가 오버라이드함
public void example() {
System.out.println("example() of SubClass");
}
}
"애너테이션@Deprecated이 붙은 대상의 필드나 메서드가 새로운 것으로 대체되었으니 기존의 것을 되도록 사용하지마세요"
public class Main {
public static void main(String[] args) {
OldClass oldClass = new OldClass();
System.out.println(oldClass.getOldField());
}
}
class OldClass{
@Deprecated
private int oldField;
@Deprecated
int getOldField(){
return oldField;
}
}
이와같은 코드를 입력하면
이렇게 취소선이 뜬다. 즉, 기존의 코드를 다른 코드와의 호환성 문제로 삭제하기 곤란해 남겨두어야만 하지만 더 이상 사용하는 것을 권장하지 않을 때에 @Deprecated를 사용한다.
"경고가 발생할 것을 예상하지만 컴파일 경고메세지를 묵인해주세요"
@SuppressWarnings({"deprecation", "unused", "null"})
"함수형 인터페이스의 선언이 바르게 선언되었나요?"
@FunctionalInterface
public interface ExampleInterface {
public abstract void example(); // 단 하나의 추상 메서드
}
@Override(표준 애너테이션의 한 종류)의 소스코드를 보자
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
@Target(ElementType.METHOD) ,@Retention(RetentionPolicy.SOURCE) 이 두개의 애너테이션은 @Override 애너테이션을 사용할 때 사용된 애너테이션이다.
이 두가지는 @Override의 적용대상과 유지기간을 지정하는 역할을 하는 애너테이션이다.
또한, 애너테이션을 정의할 때는 @interface키워드를 사용하여 정의한다.
즉 Override가 애너테이션으로 사용되기 위해선 앞에 @interface를 붙여주어야 한다.
@Target : 대상을 지정할 때 사용됨
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;
}
애너테이션을 사용자가 직접 정의할 때(@interface 사용), @Target 애너테이션을 통해 사용자가 정의한 애너테이션이 어디에 적용될 수 있는지를 설정
@Documented : 애너테이션정보를 javadoc으로 작성한 문서에 포함하라는 애너테이션 설정
표준 애너테이션의 Override와 SuppressWarnings를 제외하고는 모두 @Documented애너테이션이 포함되있음.
@Inherited : "하위클래스는 애너테이션을 상속받아라!"
@Inherited애너테이션을 상위클래스에 붙이면 하위클래스도 상위클래스에 붙은 애너테이션들이 동일하게 적용된다. 아래의 코드를 살펴보면 상위클래스를 상속받은 하위클래스는 상위클래스와 동일하게 superAnnotation에 정의된 내용을 적용받게 된다.
@Inherited // @SuperAnnotation이 하위 클래스까지 적용
@interface SuperAnnotation{ }
@SuperAnnotation
class Super { }
@SuperAnnotation //생략
class Sub extends Super{ } // Sub에 애너테이션이 붙은 것으로 인식
@Retention : "애너테이션의 지속시간을 결정해라"
애너테이션이 유지되는 기간을 정하는 속성(=유지정책)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
//오버라이딩이 제대로 되었는지 컴파일러가 확인하는 용도
//클래스 파일에 남길 필요 없이 컴파일시에만 확인하고 사라짐
public @interface Override(){ }
@Repeatable : "애너테이션을 여러번 붙일 수 있도록 허용합니다"
@Repeatable(Works.class) // Work 애너테이션을 여러 번 반복해서 쓸 수 있게 한다.
@interface Work{
String value();
}
work애너테이션을 하나의 대상에 여러번 적용하는 것이 가능함
@Work("코드 업데이트")
@Work("메서드 오버라이딩")
class Main{
... 생략 ...
}
@interface 애너테이션명 { // 인터페이스 앞에 @기호만 붙이면 애너테이션을 정의할 수 있습니다.
타입 요소명(); // 애너테이션 요소를 선언
}