본문 바로가기

하../java

ch12 어노테이션 타입 정의하기 어노테이션의 요소

어노테이션 타입 정의하기

- 어노테이션을 직접 만들어 쓸 수 있다.

@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