🎯 목표 : 애너테이션의 이해와 활용
📒 Annotation
- 프로그램의 소스코드 안에 다른 프로그램을 위한 정보를 미리 약속된 형식으로 포함시킨것
📌 특징
- 주석과 같이 프로그램 언어에 영향을 미치지 않으면서 다른 프로그램으로 정보를 제공한다
- 표준 애너테이션과 메타 애너테이션이 있다.
- 표준 애너테이션은 기본적으로 제공되는 애너테이션이다.
- 메타 애너테이션은 새로운 애너테이션을 사용자 정의할때 사용하는 애너태이션이다.
📌 표준 Annotation
- 주석과 같이 프로그램 언어에 영향을 미치지 않으면서 다른 프로그램으로 정보를 제공한다

👉 @Override
- 메소드 앞에만 붙일수 있다.
- 부모 메소드를 오버라이딩 하라는것으로 컴파일러에게 알려준다.
- 오버라이딩 할때 오타 등 실수가 발생하는것을 방지한다.
class Big {
void bigmethod () { }
}
class Small extends Big {
@Override // 오타나 제대로 오버라이딩이 되었는지 확인해준다
void bigmethod () {
}
}
👉 @ Deprecated
- 앞으로 사용하지 않을것을 권장하는 필드 , 메소드에 붙인다.
- 예들들어 Date 클래스의 getDate()
- Error는 없고 경고만 발생하며, 이는 하위호환성 때문에 경고 처리 되어있다.
👉 @ FunctionalInterface
- 함수형 인터페이스를 선언할때 애너테이션을 붙이게 되면 컴파일러가 올바르게 선언했는지 확인해준다.
- 함수형 인터페이스는 하나의 추상메소드만 가질수 있는 제약이있다.
👉 @ SupperssWarnings
- 컴파일러의 경고메세지가 나타나지 않게 억제한다.
- @SupperssWarnings("경고종류")를 입력해주면 해당 경고는 나타나지 않는다.
- 자바의 이전버전에서 발생하지 않았던 경고메세지를 확인하고 추가해줘서 나타나지 않게 하는것이 좋다.
- cmd에서 자바 컴파일러를 실행시켜 경고메세지를 확인할수 있다.
👉 @ Deprecated
- 앞으로 사용하지 않을것을 권장하는 필드 , 메소드에 붙인다.
📌 메타 Annotation
- 애너테이션을 정의할때 사용하는 애너테이션이다
- 사용자 정의 애너테이션의 적용대상, 유지기간등을 지정하는데 사용한다.
👉 @ Target
- 애너테이션이 적용가능한 대상을 지정하는데 사용한다.
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
// 위와 같이정의

- FIELD는 기본형에, TYPE_USE는 참조형에 사용된다.
@Target({FIELD, TYPE, TYPE_USE})
@interface MyAnnotation{} // 아무 기능이없는 예제 애너태이션
@MyAnnotation // TYPE
class MyClass{
@MyAnnotation // FIELD
int i;
@MyAnnotation // TYPE_USE
MyClass my;
}
👉 @ Retention
- 애너테이션이 유지되는 기간을 정하는데 사용된다.
SOURCE : 소스 파일에만 존재, 클래스 파일에는 존재하지 않는다.
CLASS : 클래스 파일에 존재, 실행시에 사용불가, 기본값
RUNTIME : 클래스 파일에 존재, 실행시에 사용가능.
- SOURCE는 컴파일러를 직접 작성할 것이 아니면, 해당 유지 기간은 필요없다.
- RUNTIME은 실행후에 클래스 파일에 저장된 애너테이션의 정보를 읽어서 처리할수 있다.
- CLASS 애너테이션의 정보를 클래스 파일에 저장할수 있게 하지만 클래스 파일이 JVM에 로딩될 때는 애너테이션의 정보가 무시되어 실행시에 정보를 알수 없다. 기본값이지만 잘 사용하지 않는다.
👉 @ Inherited
- 애너테이션을 자식 클래스에 상속되도록 한다.
- @Inherited 를 부모 클래스에 붙이게 되면 자식 클래스도 이 애너테이션이 붙은 것과 같이 인식된다.
👉 @ Repeatable
- 반복해서 붙일수 있는 애너테이션 정의할때 사용한다.
- 반복해서 붙일수 있는 애너테이션을 하나로 묶을 컨테이너 애너테이션도 정의 해야한다.
📌 사용자 정의 Annotation
- 추상메소드 문법으로 선언한다
- 애너테이션을 적용할떄는 순서 상관없이 지정할수 있다.
- 추상메소드를 구현하는 것이 아닌 값을 정의해주면 된다.
- 적용시 값을 지정하지 않았을때 사용될수 있는 기본값을 지정가능하다.
default 값은 null을 쓸수없다. - 정의한 애너테이션의 요소가 하나고 이름이 value 일때 요소의 이름을 생략하고 값만 적어 줄수 있다.
- 요소가 배열타입일 경우 {}를 써야되고 값이 하나일때는 {} 생략 가능하며, 값이 없을때는 빈 괄호를 붙이면된다.
👉 예제
- MyAnno 애너테이션을 정의하였다.
- AnnotationStudy 클래스에서 MyAnno 애너테이션을 사용하려면 ( )에 정의한 형식으로 값을 정의하고 사용해야된다.
- 변수 a는 defaulf 값을 정의 했기 때문에 애너테이션 사용당시 값을 정의하지 않았다.
- 애너테이션의 값을 main 메소드가 실행될때 얻어서 출력하려면 public 클래스의 객체를 생성후 참조변수로 애너테이션 클래스 객체를 참조변수에 초기화 해야된다.
enum TestEnum {FIRST, SCEOND}
@Retention(RetentionPolicy.RUNTIME) // 해당 애너테이션을 실행 하는동안 읽으려면 RUNTIME으로 선언
@interface MyAnno{
int a() default 1; // 변수 선언
String b(); // 문자열 변수 선언
String [] c(); // 배열 선언
TestEnum d(); // 열거형 타입의 상수를 호출할수 있게 선언한다
// String testPa(int i, int j); 애러, 매개변수를 선언할수 없다.
// String testPa throws Exception; 애러, 예외를 선언할수 없다.
// ArrayList<T> list(); 애러, 요소의 타입에 타입 매개변수를 사용할수 없다.
}
@MyAnno(b="B",c ={"A","B"}, d = TestEnum.FIRST )// a의 값은 정의하지 않았다.
public class AnnotationStudy{
public static void main(String[] args) {
Class<AnnotationStudy> cla = AnnotationStudy.class;
MyAnno an = cla.getAnnotation(MyAnno.class);
System.out.println(an.a());
System.out.println(an.b());
System.out.println(Arrays.toString(an.c()));
System.out.println(an.d());
Annotation[] anArray = cla.getAnnotations(); // 애너테이션의 정의된 모든 정보를 배열로 가져온다.
for (Annotation i : anArray)
System.out.println(i);
}
}
==== 출력값 ====
1
B
[A, B]
FIRST
@MyAnno(a=1, b="B", c={"A", "B"}, d=FIRST)'Language > JAVA' 카테고리의 다른 글
| Java Thread_02 (0) | 2022.09.05 |
|---|---|
| Java Thread_01 (0) | 2022.09.04 |
| Java 열거형 (0) | 2022.09.03 |
| Java Generics (0) | 2022.09.03 |
| Java Memory Structure (0) | 2022.09.03 |