공부/Java

[Java] Annotation - 어노테이션 (자바의 정석)

leejinwoo1126 2023. 7. 19. 21:40
반응형

 

 


자주 사용하는 표준 어노테이션

 

@Override 

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

 

@Deprecated

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

 

@FunctionalInterface

- 함수형 인터페이스는 하나의 추상메서드만 가져야 한다는 제약이 있음

- 함수형 인터페이스에 붙이면, 컴파일러가 제대로 작성했는지 체크

- 함수형 인터페이스라고 명시적으로 알려줌

 

@SuppressWarnings

- 컴파일러가 경고 메시지가 나타나지 않게 한다. 

- 명시적으로 경고를 확인하고 억제하기 위해 붙였다는 의미를 나타내기도 함

# 한 가지
@SuppressWarnings("unchecked")
List list = new ArraysList(); // 제네릭 타입 지정하지 않아 발생하는 오류 표시 제거

# 두 가지 이상 
@SuppressWarnings({"deprecation", "unchecked", "all"})

- '-Xlint' 옵션으로 컴파일시 경고 종류 확인 가능

 

옵션 참고. https://www.baeldung.com/java-suppresswarnings-valid-names

 


메타 어노테이션

java.lang.annotation 패키지에 포함

 

@Target

어노테이션 적용 대상 지정

package java.lang.annotation;

public enum ElementType {
   TYPE,
   FIELD,
   METHOD,
   PARAMETER,
   CONSTRUCTOR,
   LOCAL_VARIABLE,
   ANNOTATION_TYPE,
   PACKAGE,
   TYPE_PARAMETER,
   TYPE_USE,
   MODULE;

   private ElementType() {
   }
}

 

 

 

@Retention 

어노테이션이 유지(retention)되는 기간 지정

package java.lang.annotation;

public enum RetentionPolicy {
   SOURCE,  // 컴파일러에 의해 무시
   CLASS,   // 런타임 시 무시 (컴파일 시에만 체크)
   RUNTIME; // 런타임 시에도 확인

   private RetentionPolicy() {
   }
}

 

아래의 3개 어노테이션(@Documented, @Inherited, @Repeatable)은 보통 사용하는 경우가 없기 때문에 알아두기만 한다. 

@Documented 

javadoc으로 작성한 문서에 포함시킴 

 

@Inherited

어노테이션을 부모 클래스에 붙여서 자식 클래스에 상속하는 용도

 

@Repeatable 

- 반복해서 붙일 수 있는 어노테이션을 정의 

- @Repeatable이 붙은 어노테이션은 반복해서 붙일 수 있다. 

 

import java.lang.annotation.Repeatable;

@Repeatable(Schedules.class)
public @interface Schedule {
	String dayOfMonth() default "first";
    String dayOfWeek() default "Mon";
    int hour() default 12;
}

- 이때 @Repeatable 메타 어노테이션의 괄호(parentheses)안에 있는 타입은 container annotation 으로 Java Compiler가 반복되는 @Schedule 어노테이션을 저장하는 용도로 사용

 

// container annotation
public @interface Schedules {
	Schedule[] value();
}

 

사용 예시

@Schedule(dayOfMonth="last")
@Schedule(dayOfWeek="Fri", hour="23")
public void doSomething() { .. }

- 클래스의 메타 어노테이션 정보 또한 조회 가능 (예. Reflection API)

 

https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html

 

Repeating Annotations (The Java™ Tutorials > Learning the Java Language > Annotations)

The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See Java Language Changes for a summary of updated

docs.oracle.com


어노테이션 타입 직접 정의하기

// 형식
@interface 어노테이션명 {
	타입 요소이름();  
}

- 어노테이션의 메서드는 추상 메서드

 

 

예시

@interface TestInfo {
    int count() defaul 1;
    String[] tests();
    TestType testType(); // enum type 
    DateTime testDate(); // 다른 어노테이션 (@DateTime)을 포함할 수 있다.
}

@interface DateTime() {
    String hour;
    String minute;
}


@TestInfo(
    count=3, 
    tests={"A", "B"},
    testType=TestType.JUNIT,
    testDate=@DateTime(hour="12", minute="00")
)
public class SomethingClass { ... }

- 순서는 상관없음

 

 

어노테이션의 요소

(1) 기본값 (default) 을 지정 가능 (null은 제외) 

@interface Test {
	int count() default 1;
}

@Test // @Test(count = 1) 과 동일
public class EmptyClass {...}

 

(2) 요소가 하나이고 명칭이 value일때는 요소 명칭 생략가능

@interface Test {
   String value();
}

@Test("junit")
class EmptyClass {...}

 

(3) 요소의 타입이 배열인 경우, 괄호{} 사용해야 함

@interface Test {
   String[] arrays; // default 가능
}

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

 

어노테이션의 조상 

- java.lang.annotation.Annotation

- interface Annotation의 추상 메서드를 구현하지 않고도 사용가능 ( 클래스의 조상 Object와 비슷)

 

 

마커 어노테이션(Marker Annotation)

- 어노테이션에 정의된 요소가 없는 어노테이션 (예 @Test, @Deprecated)

- 어노테이션 자체만으로 의미 전달 가능

 

(사용자 정의) 어노테이션을 명시한 Method 실행시간 측정하는 용도
실행시간 측정하여 로그로 출력

 


참고 

남궁성의 자바의 정석 https://www.youtube.com/watch?v=81U0MyuZQKo 

 

반응형