Day 59

ChangWoo·2023년 6월 3일
0

자바의 정석

목록 보기
56/71
post-thumbnail

ch 12-29~33 메타 애너테이션

메타 애너테이션

  • 메타 애너테이션은 '애너테이션을 위한 애너테이션'
  • 메타 애너테이션은 java.lang.annotation패키지에 포함
  • 애너테이션을 만들 때 사용

@Target

  • 애너테이션을 정의할 때, 적용대상 지정에 사용
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
	String[] value();
}


<@Target 애너테이션의 예>

  • @interface MyAnnotation : MyAnnotation을 만들 때, @interface를 붙여준다.
  • MyAnnotation을 FIELD, TYPE, TYPE_USE에만 붙일 수 있다.
  • @MyAnnotation = 클래스, 인터페이스일 때만 사용가능
  • FIELD = iv(멤버변수)일 때
  • TYPE_USE = 참조변수일 때

@Retention

  • 애너테이션이 유지(retention)되는 기간을 지정하는데 사용
  • 컴파일러에 의해 사용되는 애너테이션의 유지 정책은 SOURCE이다.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {}
  • 실행시에 사용 가능한 애너테이션의 정책은 RUNTIME이다.
@Documented
@Retention(RetentionPolicy.RUNTIME) // RUNTIME까지
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

@Documented, @Inherited

  • javadoc으로 작성한 문서에 포함시키려면 @Documented를 붙인다.
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface{}
  • 애너테이션을 자손 클래스에 상속하고자 할 때, @Inherited를 붙인다.
@Inherited					// @SuperAnno가 자손까지 영향 미치게
@interface SuperAnno {}
@SuperAnno
class Parent {}
class Child extends Parent {} // child에 애너테이션이 붙은 것으로 인식

@Repeatable

  • 반복해서 붙일 수 있는 애너테이션을 정의할 때 사용
@Repeatable(ToDos.class) // ToDo애너테이션을 여러 번 반복해서 쓸 수 있게 한다.
@interface ToDo {
	String value();
}
  • @Repeatable이 붙은 애너테이션은 반복해서 붙일 수 있다.
@ToDo("delete test codes.")
@ToDo("override inherited methods")
class MyClass {
	...
}
  • @Repeatable인 @ToDo를 하나로 묶을 컨테이너 애너테이션도 정의해야 함
@interface ToDos {	// 여러 개의 ToDo 애너테이션을 담을 컨테이너 애너테이션 ToDos
	ToDo[] value();	// ToDo애너테이션 배열타입의 요소를 선언. 이름이 반드시 value이어야 함
}

ch 12-34~37 애너테이션 타입 정의하기, 애너테이션의 요소

애너테이션 타입 정의하기

  • 애너테이션을 직접 만들어 쓸 수 있다.
@interface 애너테이션이름 {
	타입 요소이름(); // 애너테이션의 요소를 선언한다.
    	...
}

< Ex >

@interface DateTime {
	String yymmdd();
    String hhmmss();
}
  • 애너테이션의 메서드는 추상 메서드이며, 애너테이션을 적용할 때 지정(순서X)
@interface TestInfo {
	int		 count();
    String	 testedBy();
    String[] testTools();
    TestType testType(); // enum Testtype { FIRST, FINAL }
    DateTime testDate(); // 자신이 아닌 다른 애너테이션(@DateTime)을 포함할 수 있다.

  • 애너테이션을 만들면, 이름과 타입에 맞게 적어서 사용하면 된다.
  • 추상메서드를 구현할 필요가 없다.

애너테이션의 요소

  • 적용시 값을 지정하지 않으면, 사용될 수 있는 기본값 지정 가능(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();
}

모든 애너테이션의 조상 - 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 hahsCode();
    String toString();
    class<? extends Annotation> annotationType(); // 애너테이션의 타입을 반환
}
  • Annotation은 추상메서드들을 가지고 있으며 구현은 불가하지만, 사용은 가능하다.

마커 애너테이션 - Marker Annotation

  • 요소가 하나도 정의되지 않은 애너테이션
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {} // 마커 애너테이션. 정의된 요소가 하나도 없다.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Test {} // 마커 애너테이션. 정의된 요소가 하나도 없다.
@Test // 이 메서드가 테스트 대상임을 테스트 프로그램에게 알린다.
public void method() {
	...
}
@Deprecated
public int getDate() {
	return normalize().getDayOfMonth();
}

애너테이션 요소의 규칙

  • 애너테이션의 요소를 선언할 때 아래의 규칙을 반드시 지켜야 한다.
    • 요소의 타입은 기본형, String, enum, 애너테이션, Class만 허용됨
    • 괄호()안에 매개변수를 선언할 수 없다.
    • 예외를 선언할 수 없다.
    • 요소를 타입 매개변수로 정의할 수 없다.
  • 아래의 코드에서 잘못된 부분은?
@interface AnnoTest {
	int id = 100;						// 상수OK, default메서드 X
    String major(int i, int j);         // 매개변수 X
    String minor() throws Exception;    // 예외 선언 X
    ArrayList<T> list();				// 매개변수 X
}
profile
한 걸음 한 걸음 나아가는 개발자

0개의 댓글