본문 바로가기
개발공부/개념정리

@Annotation 개념 및 사용방법

by parkman

1. Annotation 이란?

자바 애너테이션(Java Annotation)은 자바 소스 코드에 추가하여 사용할 수 있는 메타데이터의 일종이다. 보통 @ 기호를 앞에 붙여서 사용한다. JDK 1.5 버전 이상에서 사용 가능하다. 자바 애너테이션은 클래스 파일에 임베디드되어 컴파일러에 의해 생성된 후 자바 가상머신에 포함되어 작동한다.

(위키백과)

 

2. 어노테이션의 용도

  1. 컴파일러에게 코드 작성 문법 에러를 체크하도록 정보를 제공
  2. 소프트웨어 개발툴이 빌드나 배치시 코드를 자동으로 생성할 수 있도록 정보 제공
  3. 실행시(런타임시)특정 기능을 실행하도록 정보를 제공

3. 노테이션의 종류

어노테이션에도 종류가 있다.

  • 표준(내장) 어노테이션 : 자바가 기본적으로 제공해주는 어노테이션
  • 메타 어노테이션 : 어노테이션을 위한 어노테이션
  • 사용자정의 어노테이션 : 사용자가 직접 정의하는 어노테이션

1) 표준 어노테이션

표준 어노테이션(메타 어노테이션 제외)의 종류는 다음과 같다.

@Override

오버라이딩을 올바르게 했는지 컴파일러가 체크한다.

Override는 오버라이딩할 때, 메서드의 이름을 잘못적는 실수를 방지해준다.

@Deprecated

앞으로 사용하지 않을 것을 권장하는 필드나 메서드에 붙인다.

자바에서 메소드를 사용했는데 다음과 같이 표시된 경험이 있을 것이다.
"getDate()"
이유는 해당 메소드 상위에 @Deprecated 어노테이션이 붙어있기 때문이다.

자바의 Date 클래스의 getDate()

@Deprecated
public int getDate(){
	return normalize().getDayOfMonth();
}

위의 "getDate" 메서드는 자바에서 사용하지 않을 것을 권장하는 메소드이다.

없애지 않는 이유는?
자바는 하위 호환성을 엄청나게 중요하게 여긴다. 이전에 해당 메소드로 개발을 진행한 프로젝트들이 있기 때문에 유지는 하되, 권장하지 않는다.

@SuppressWarnings

컴파일러의 경고메세지가 나타나지 않게 한다.

@SuppressWarnings("unchecked")
ArrayList list = new ArrayList(); // 제네릭 타입을 지정하지 않음!
list.add(obj); // 경고 발생 !!! 경고 내용 = unchecked

위의 코드를 보자.
Array를 선언할 때 제네릭을 통해서 타입에 대한 정보를 기입하지 않았다.
그래서 타입을 선언하지 않았다는 "unchecked"라는 경고가 뜬다.
하지만 "@SuppressWarnings("unchecked)"를 입력해주었기 때문에 "unchecked"에 대한 경고는 억제된다.

보통 경고가 많을 때, 확인된 경고는 해당 어노테이션을 붙여서 새로운 경고를 알아보지 못하는 것을 방지하기 위해 사용한다.

 

2) 메타 어노테이션

메타 어노테이션의 종류는 다음과 같다.

@Target

어노테이션을 정의할 때, 적용대상을 지정하는데 사용한다.

@Target({TYPE, FIELD, TYPE_USE})
@Retention(RetentionPolicy.SOURCE)
public @interface MyAnnotation{}

@MyAnnotation // 적용 대상이 Type(클래스, 인터페이스)
class MyClass{
	@MyAnnotation //적용 대상이 FIELD인 경우
    int i;
    
    @MyAnnotation //적용 대상이 TYPE_USE인 경우
    MyClass mc;
}

@Retention

어노테이션이 유지되는 기간을 지정하는데 사용

  • SOURCE : 소스 파일에만 존재.
  • RUNTIME : 클래스 파일에 존재. 실행시에 사용가능
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override{}

@Documented

javadoc으로 작성한 문서에 포함시키려면 해당 어노테이션을 붙인다.

@Inherited

어노테이션도 상속이 가능하다. 어노테이션을 자손 클래스에 상속하고자 할 때, @Inherited를 붙인다.

@Inherited
@interface SuperAnno{}

@SuperAnno
class Parent{}

// <- 여기에 @SuperAnno 가 붙은 것으로 인식
class Child extends Parent{}

@Repeatable

반복해서 붙일 수 있는 어노테이션을 정의할 때 사용

@Repeatable(ToDos.class)
@interface ToDo{
	String value();
}

@ToDo("delete test codes.")
@ToDo("override inherited methods")
class MyClass{
	~~
}

@interface ToDos{
	ToDo[] value();
}

4.어노테이션 생성하기

다음 코드와 같이 작성한다.

@interface 이름{
	타입 요소 이름(); // 어노테이션의 요소를 선언
	    ...
}

실제로 만들고, 적용해보자.

@interface DateTime{
	String yymmdd();
    String hhmmss();
}

@interface TestInfo{
	int count() default 1;
    String testedBy();
    TestType testType();
    DateTime testDate();
}


@TestInfo{
	testedBy="Kim",
    testTools={"JUnit", "AutoTester"},
    testType=TestType.FIRST,
    testDate=@DateTime(yymmdd="210922", hhmmss="211311")
)// count를 생략했으므로 default인 "count=1"이 적용된다.
public class NewClass{...}

 

어노테이션 요소 특징

  • 적용시 값을 지정하지 않으면, 사용될 수 있는 기본값을 지정할 수 있다.(위의 default)
  • 요소가 하나이고 이름이 value일 때는 요소의 이름 생략가능하다.
@interface TestInfo{
	String value();
}
@TestInfo("passed") // value="passed"와 동일
class NewClass{...}
  • 요소의 타입이 배열인 경우, 괄호{}를 사용해야 한다.
@interface TestInfo{
	String[] testTools();
}

@TestInfo(testTools={"JUnit", "AutoTester"})
@TestInfo(testTools="JUnit") // 요소가 1개일 때는 {}를 사용하지 않아도 된다.
@TestInfo(testTool={}) // 요소가 없으면 {}를 써넣어야 한다.

모든 어노테이션의 조상

 

Annotation은 모든 어노테이션의 조상이지만 상속은 불가능하다.

public interface Annotation{
	boolean equals(Object obj);
    int hashCode();
    String toString();
    
    Class<? extends Annotation> annotationType();
    }

마커 어노테이션

요소가 하나도 정의되지 않은 어노테이션

 

대표적으로 "@Test"가 있다.
해당 어노테이션은 테스트 프로그램에게 테스트 대상임을 알리는 어노테이션이다.

어노테이션 규칙

어노테이션에도 반드시 지켜주어야 하는 규칙이 있다. 다음 4가지를 살펴보자.

  • 요소의 타입은 기본형, String, enum, 어노테이션, Class만 허용된다.
  • 괄호()안에 매개변수를 선언할 수 없다.
  • 예외를 선언할 수 없다.
  • 요소의 타입을 매개변수로 정의할 수 없다.(<T>)

잘못된 예시를 통해서 이해해보자!

@interface AnnoConfigTest{
    int id = 100; // 상수 ok
    String major(int i, int j) //매개변수 x
    String minor() throws Exception; // 예외 x
    ArrayList<T> list(); // 요소의 타입을 매개변수 x

 

 

 

 

 

 

 

 

 

 

 

https://velog.io/@jkijki12/annotation

728x90
반응형
LIST

'개발공부 > 개념정리' 카테고리의 다른 글

Redis (Remote Dictionary Server)  (2) 2022.06.08
HTTP, HTTPS, SSL, TLS  (0) 2022.06.07
Spring - Filter, Interceptor, AOP 개념 차이  (0) 2022.04.14
REST API(RESTful API)  (0) 2022.04.01
Spring Security 란?  (0) 2022.03.22