본문 바로가기

Java

애너테이션

출처 - Java의 정석 기초편 (남궁 성)

 

 

1. 애너테이션이란?

- @태그: 주석처럼 프로그래밍 언어에 영향을 미치지 않고 유용한 정보 제공

- 소스코드 + 소스코드 설명 문서: 주석 /** ~ */ 에 소스 코드에 대한 정보 저장

- javadoc.exe: 소스파일에서 주석 추출해 HTML문서 생성

 

/** 소스코드 주석
@link // 유용한 정보 제공
@author
@since
*/
소스코드

 

 

2. 표준 애너테이션

- 자바에서 기본적으로 제공

 

@Override
@Deprecated
@SuppressWarnings
@SafeVarargs
@FunvtionalInterface
@Native

 

 

@Override

- 컴파일러에게 메서드 오버라이딩하는 것임을 알림

- 오버라이딩 올바르게 했는지 컴파일러가 체크

- 메서드 앞에 @Override 붙이는 습관

 

class Child extends Parent {
    @Override
    void parentmethod() {}
}

 

 

@Deprecated

- 앞으로 사용하지 않을 것을 권장하는 필드나 메서드

- 컴파일하면 경고 발생

 

class NewClass {
    @Deprecated
    int oldField;
    
    @Deprecated
    int getOldField() { return oldField; };
}

 

 

@FunctionalInterface

- 함수형 인터페이스 올바르게 작성했는지 컴파일러가 체크→잘못된 경우 에러 발생

- 함수형 인터페이스 추상 메서드 하나뿐이어야 함

 

@FunctionalInterface
public interface Runnable {
    public abstract void run(); // 추상 메서드 1개 제약
}

 

 

@SuppressWarnings

- 컴파일러의 경고 메시지 억제

- 괄호() 안에 억제하려는 경고 종류를 문자열로 지정

- 둘 이상의 경고를 동시에 억제하려면 괄호{} 사용

 

@SuppressWarnings("unchecked") // 지네릭스와 관련된 경고 억제
@SuppressWarnings({"deprecation", "unchecked", "varargs"})

 

 

3. 메타 애너테이션

- 애너테이션 만들 때 사용

- java.lang.annotation 패키지에 포함

 

@Target
@Documented
@Inherited
@Retention
@Repeatable

 

 

@Target

- 애너테이션 정의시 적용대상 지정

- 여러 개의 값 지정시 괄호{} 사용

 

import static java.lang.annotation.ElementType.*;

@Target({FIELD, TYPE, TYPE_USE})
public @interface MyAnnotation {} // MyAnnotation 정의

@MyAnnotation // 적용대상 TYPE
class MyClass {
    @MyAnnotation // 적용대상 FIELD
    int i;
    @MyAnnotation // 적용대상이 TYPE_USE
    MyClass mc;
}

 

 

@Retention

- 애너테이션 유지되는 기간 지정

- 유지 정책(retention policy)

- SOURCE: 소스 파일에만 존재

- CLASS: 클래스 파일에 존재, 실행시 사용불가

- RUNTIME: 클래스 파일에 존재, 실행시 사용가능

 

// 컴파일러가 사용하는 애너테이션 유지정책(SOURCE)
@Target(ElementType.METHOD)
@Retention(retentionPolicy.SOURCE)
public @interface Override {}

// 실행시 사용 가능한 애너테이션 유지정책(RUNTIME)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

 

 

@Documented, @Inherited

- javadoc으로 작성한 문서에 포함

- 애너테이션을 자손 클래스에 상속

 

@Inherited
@interface SuperAnno {}

@SuperAnno
class Parent {}

class Child extends Parent {} // Child에 애너테이션 붙은 것으로 인식

 

 

@Repeatable

- 반복해서 붙일 수 있는 애너테이션 정의시 사용

- @Repeatable인 @ToDo를 하나로 묶을 컨테이너 애너테이션 추가 정의

 

@interface ToDos { // 컨테이너 애너테이션 ToDos
    ToDo[] value(); // ToDo애너테이션 배열타입의 요소 선언(이름 반드시 value)
}

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

@ToDo("delete test code.")
@Todo("override inherited methods")
class MyClass {
    ...
}

 

 

4. 애너테이션 타입 정의

- 애너테이션 요소: 추상 메서드 형태(구현 안함)

- 애너테이션 적용시 지정: 순서 상관 없음

- 적용시 값 지정하지 않으면 사용될 수 있는 기본값 지정 가능

- 요소 하나이고 이름이 value인 경우 적용시 이름 생략가능

- 요소 타입이 배열인 경우 괄호{} 사용(값이 하나면 생략 가능, 값이 없으면 반드시 필요)

 

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

// 5개 요소 선언
@interface TestInfo {
    int count() default 1; // 기본값을 1로 지정
    String testedBy();
    String[] testTools(); // 배열
    TestType testType(); // enum
    DateTime testDate(); // 다른 애너테이션
}

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

// 요소의 값 지정(순서 상관 없음)
@TestInfo ( // count=1
    testedBy="KIM",
    testTools={"Junit", "AutoTester"},
    testType=TestType.FIRST,
    testDate=@DateTime(yymmdd="22.11.07", hhmmss="173959")
)
public class NewClass {...}

// 사용
anno.count() // 3

 

 

5. 모든 애너테이션 조상

- Annotation: 모든 애너테이션의 조상이지만 상속 불가

- 자신은 인터페이스→equals(), hashCode(), toString() 추상메서드 구현 없이, 모든 애너테이션 객체에 호출 가능

 

@interface TestInfo extends Annotation // 에러. 상속 불가

 

 

6. 마커 애너테이션

- 요소가 하나도 정의되지 않은 애너테이션

- Override, Test, Deprecated 등

 

@Target(elementtype.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Test {} // 정의된 요소가 없음

 

 

7. 애너테이션 요소 규칙

- 요소 타입은 기본형, String, enum, 애너테이션, Class(설계도 객체)만 허용

- 매개변수 선언 불가

- 예외 선언 불가

- 요소 타입에 타입 매개변수<T> 사용 불가

 

 

 

'Java' 카테고리의 다른 글

쓰레드 메서드  (0) 2022.11.19
쓰레드(thread)  (0) 2022.11.17
열거형(enum)  (0) 2022.11.04
지네릭스(Generics)  (0) 2022.11.04
HashMap, TreeMap, Collections  (0) 2022.10.30