Notice
Recent Posts
Recent Comments
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
관리 메뉴

충분히 쌓여가는

애너테이션 타입 정의하기, 애너테이션의 요소 본문

Java/JAVA3

애너테이션 타입 정의하기, 애너테이션의 요소

빌드이너프 2023. 8. 1. 10:37

애너테이션 타입 정의하기

애너테이션을 직접 만들어 쓸 수 있다

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

 

예시

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

 

 

애너테이션의 메서드는 추상 메서드이며, 애너테이션을 적용할 때 지정(순서 X)

@interface TestInfo {
    int count();
    String testBy();
    String[] testTools();
    TestType testType(); // enum TestType { FIRST, FINAL }
    DateTime testDate(); // 자신이 아닌 다른 애너테이션(@DateTime)을 포함할 수 있다
}

 

사용

@TestInfo (
    count=3, testedBy="Kim",
    testTools={"JUnit", "AutoTester"},
    testType=TestType.FIRST,
    testDate=@DateTime(yymmdd="160101", hhmmss=="235959")
)
public class NewClass { ... }

 

에너테이션의 요소

적용시 값을 지정하지 않으면, 사용될 수 있는 기본값 지정 가능(null 제외)

@interface TestInfo {
    int count() default 1; // 기본값을 1로 지정
}

@TestInfo // @TestInfo(count=1)과 동일
public class NewClass { ... }

 

요소가 하나이고 이름이 value일 때는 요소의 이름 생략 가능

@interface TestInfo {
    String value();
}

@TestInfo("passed") // @TestInfo(value="passed")와 동일
class NewClass { ... }

 

요소의 타입이 배열인 경우, 괄호{}를 사용해야 한다

@interface TestInfo {
    String[] testTools();
}

 

@Test(testTools={"JUnit", "AutoTester"})
@Test(testTools="JUnit")
@Test(testTools={}) // 값이 없을 때는 괄호{}가 반드시 필요

 

모든 애너테이션의 조상 - java.lang.annotation.Annotation

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

@interface TestInfo extends Annotation { // 에러, 허용되지 않는 표현
    int count();
    String testedBy();
        ...
}

 

사실 Annotation은 인터페이스이다

package java.lang.annotation;

public interface Annotation { // Annotation 자신은 인터페이스이다
    boolean equals(Object obj);
    int hashCode();
    String toString(0;
    
    Class<? extends Annotation> annotationType(); // 애너테이션의 타입을 반환
}

 

Marker Annotation - 마커 애너테이션

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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {} // 마커 애너테이션, 정의된 요소가 하나도 없다

@Target(ElementType.MEHTOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Test {} // 마커 애너테이션, 정의된 요소가 하나도 없다

 

@Test // 이 메서드가 테스트 대상임을 테스트 프로그램에게 알린다
public void method() {
    ...
}

 

애너테이션 요소의 규칙

애너테이션의 요소를 선언할 때 아래의 규칙을 반드시 지켜야 한다

1. 요소의 타입은 기본형, String, enum, 애너테이션, Class만 허용됨

2. 괄호() 안에 매개변수를 선언할 수 없다

3. 예외를 선언할 수 없다

4. 요소를 타입 매개변수<T>로 정의할 수 없다

 

잘못된 코드 예시

@interface AnnoTest {
    int id = 100; // OK, 상수(기본형)
    String major(int i, int j); // 에러, 매개변수 가질 수 없다
    String minor() throws Exception; // 에러, 예외 선언 불가
    ArrayList<T> list(); // 에러, 타입매개변수 사용 불가
}

 

코드

import java.lang.annotation.*;

@Deprecated
@SuppressWarnings("1111") // 유효하지 않은 애너테이션은 무시된다.
@TestInfo(testedBy="aaa", testTools= {"JUnit", "JUnit5"}, testDate=@DateTime(yymmdd="160101",hhmmss="235959"))
class annotationTest {
    public static void main(String args[]) {
        // annotationTest의 Class객체를 얻는다.
        Class<annotationTest> cls = annotationTest.class;

        TestInfo anno = cls.getAnnotation(TestInfo.class);
        System.out.println("anno.testedBy()="+anno.testedBy());
        System.out.println("anno.testDate().yymmdd()=" +anno.testDate().yymmdd());
        System.out.println("anno.testDate().hhmmss()=" +anno.testDate().hhmmss());

        for(String str : anno.testTools())
            System.out.println("testTools="+str);

        System.out.println();

        // annotationTest에 적용된 모든 애너테이션을 가져온다.
        Annotation[] annoArr = cls.getAnnotations();

        for(Annotation a : annoArr)
            System.out.println(a);
    }
}

@Retention(RetentionPolicy.RUNTIME)  // 실행 시에 사용가능하도록 지정
@interface TestInfo {
    int       count()	  	default 1;
    String    testedBy();
    String[]  testTools() 	default "JUnit";
    TestType  testType()    default TestType.FIRST;
    DateTime  testDate();
}

@Retention(RetentionPolicy.RUNTIME)  // 실행 시에 사용가능하도록 지정
@interface DateTime {
    String yymmdd();
    String hhmmss();
}

enum TestType { FIRST, FINAL }


anno.testedBy()=aaa
anno.testDate().yymmdd()=160101
anno.testDate().hhmmss()=235959
testTools=JUnit
testTools=JUnit5

@java.lang.Deprecated(forRemoval=false, since="")
@TestInfo(count=1, testType=FIRST, testTools={"JUnit", "JUnit5"}, testedBy="aaa", testDate=@DateTime(yymmdd="160101", hhmmss="235959"))

'Java > JAVA3' 카테고리의 다른 글

쓰레드의 구현과 실행  (0) 2023.08.02
thread 쓰레드  (0) 2023.08.02
메타 애너테이션  (0) 2023.08.01
Annotation(애너테이션) @  (0) 2023.07.31
열거형에 멤버 추가하기  (0) 2023.07.31