어노테이션 타입 정의하기
- 어노테이션을 직접 만들어 쓸 수 있다.
@interface 어노테이션이름{
타입 요소이름(); //어노테이션이 요소를 선언한다.
}
- 어노테이션의 메소드는 추상 메소드이며 어노테이션을 적용할때 지정(순서X)
@interface DateTime{
String yymmdd(); //날짜
String hhmmss(); //시간
}
@interface TestInfo{
int count();
String testedBy();
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일 때는 요소의 이름 생략가능 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={})//값이 없을 때는 괄호{}가 반드시 필요 배열도 default값 가능
모든 어노테이션의 조상 - java.lang.annotation.Annotation
- Annotation은 모든 어노테이션의 조상이지만 상속은 불가
@interface TestInfo extends Annotation{ //에러 허용되지 않는 표현
int count()
...
}
-사실 Annotation은 인터페이스이다
package java.lang.annotation;
public interface Annotation{ //Annotation자신은 인터페이스이다.
//아래 추상메소드를 구현하지 않아도 사용가능
boolean equals(Object obj);
int hashCode();
String toString();
Class<? extends Annotation> annotationType(); //어노테이션의 타입을 반환
}
마커 어노테이션 - Marker Annotation
- 요소가 하나도 정의되지 않은 어노테이션
@Test //이 메소드가 테스트 대상임을 테스트 프로그램에 알린다
public void method(){
}
@Deprecated
public int getDate(){
return normalize().getDayOfMonth();
}
어노테이션 요소의 규칙
- 어노테이션의 요소를 선언할때 아래의 규칙을 반드시 지켜야한다
- 요소의 타입은 기본형, String, enum, 어노테이션, Class만 허용됨
- 괄호()안에 매개변수를 선언할 수 없다.
- 예외 선언할 수 없다
- 요소를 타입 매개변수<T>로 정의할 수 없다
아래 코드에서 잘못된 부분 찾기
@interface AnnoTest{
int id = 100; //상수 ok default메소드 안됨
String major(int i, int j); //매개변수 int i, int j 안됨
String minor() throws Exception; //예외처리 안됨
ArrayList<T> list(); //타입 매개변수 <T> 쓸수없음
}
@Deprecated
@SuppressWarnings("1111") // 유효하지 않은 애너테이션은 무시된다.
@TestInfo(testedBy="aaa", testDate=@DateTime(yymmdd="160101",hhmmss="235959"))
class Ex12_8 {
public static void main(String args[]) {
// Ex12_8의 Class객체를 얻는다.
Class<Ex12_8> cls = Ex12_8.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();
// Ex12_8에 적용된 모든 애너테이션을 가져온다.
Annotation[] annoArr = cls.getAnnotations();
for(Annotation a : annoArr)
System.out.println(a);
} // main의 끝
}
@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
@java.lang.Deprecated()
@TestInfo(count=1, testType=FIRST, testTools=[JUnit], testedBy=aaa, testDate=@DateTime(yymmdd=160101, hhmmss=235959))
'하.. > java' 카테고리의 다른 글
| ch13 스레드 실행제어 sleep() interrupt() (0) | 2021.12.25 |
|---|---|
| ch13 데몬 스레드, 스레드의 상태 (0) | 2021.12.25 |
| ch12 메타 어노테이션 (0) | 2021.12.25 |
| ch12 표준 어노테이션 (0) | 2021.12.25 |
| ch12 어노테이션이란? (0) | 2021.12.25 |