애너테이션

애너테이션은 소스 코드가 컴파일되거나 실행될 때 컴파일러 및 다른 프로그램에게 필요한 정보를 전달해 주는 문법 요소입니다.

  • 표준 애너테이션 : JDK에 내장된 일반적인 애너테이션입니다.
  • 메타 애너테이션 : 다른 애너테이션을 정의할 때 사용하는 애너테이션입니다.

1. 표준 애너테이션

@Override

@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가 붙은 메서드와 같은 이름을 가진 메서드가 상위 클래스(또는 인터페이스)에 존재하는지 검사합니다. 즉, SuperClass에 example()이 존재하는지 검사합니다.
  • 만약, 상위 클래스(또는 인터페이스)에서 @Override가 붙어있는 메서드명과 같은 이름의 메서드를 찾을 수 없다면 컴파일러가 컴파일 에러를 발생시킵니다.

  • 만약 메서드의 이름이 다를 경우,
  • @Override를 붙이지 않으면 컴파일러는 exapmle()이라는 새로운 메서드를 정의하는 것으로 간주하고, 에러를 발생시키지 않습니다.
  • 실행 시에 런타임 에러가 발생할 것이며, 런타임 에러 발생 시에, 어디에서 에러가 발생했는지 에러의 원인을 찾아내기 어려워집니다.

  • @Override를 사용하면 example()이 오버라이딩 메서드라는 것을 컴파일러가 인지하고, 상위 클래스에 example()이 존재하는지 확인하기 때문에, 이러한 상황을 방지할 수 있습니다.

@Deprecated

기존의 코드를 다른 코드와의 호환성 문제로 삭제하기 곤란해 남겨두어야만 하지만 더 이상 사용하는 것을 권장하지 않을 때 @Deprecated를 사용합니다.

@SuppressWarnings

컴파일 경고 메시지가 나타나지 않도록 합니다. 때에 따라서 경고가 발생할 것이 충분히 예상됨에도 묵인해야 할 때 주로 사용합니다.

@FunctionalInterface

컴파일러가 함수형 인터페이스의 선언이 바르게 선언되었는지 확인하도록 합니다. 만약 바르게 선언되지 않은 경우, 에러를 발생시킵니다.

2. 메타 애너테이션

  • 메타 애너테이션(meta-annotation)은 애너테이션을 정의하는 데에 사용되는 애너테이션으로, 애너테이션의 적용 대상 및 유지 기간을 지정하는 데에 사용됩니다.

@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;
}

@Documented

애너테이션에 대한 정보가 javadoc으로 작성한 문서에 포함되도록 하는 애너테이션 설정입니다.

@Inherited

하위 클래스가 애너테이션을 상속받도록 합니다. @Inherited 애너테이션을 상위 클래스에 붙이면, 하위 클래스도 상위 클래스에 붙은 애너테이션들이 동일하게 적용됩니다.

@Retention

특정 애너테이션의 지속 시간을 결정하는 데 사용합니다.

@Repeatable

애너테이션을 여러 번 붙일 수 있도록 허용한다는 의미가 있습니다.

@Repeatable(Works.class) // Work 애너테이션을 여러 번 반복해서 쓸 수 있게 한다.  
@interface Work{  
    String value();  
}
@Work("코드 업데이트")  
@Work("메서드 오버라이딩")  
class Main{  
}