// 애너테이션(Annotation)
- 주석처럼 프로그래밍 언어에 영향을 미치지 않으며 유용한 정보 제공함.
@Override : 오버라이딩을 올바르게 했는지 컴파일러가 체크하게 함.
class Parent {
void parentMethod() {}
}
public class Ex06 extends Parent {
@Override
void parentMethod() {}
}
@Deprecated : 앞으로 사용하지 않을 것을 권장하는 필드나 메서드에 붙임.
@Deprecated
public int getDate() {
return normalize().getDayOfMonth();
}
@FunctionalInterface : 함수형 인터페이스에 붙이면, 컴파일러가 올바르게 작성했는지 체크함.
@FunctionalInterface
public interface Runnable { //함수형 인터페이스는 추상 메서드 하나만 가질 수 있음.
public abstract void run();
//void check(); 추가할 경우 에러!
}
@SuppressWarnings : 컴파일러의 경고 메세지가 나타나지 않게 억제함.
~ deprecation : @Deprecated가 붙은 대상을 사용해서 발생하는 경고
~ unchecked : 지네릭스로 타입을 지정하지 않았을 때 발생하는 경고
~ rawtypes : 지네릭스를 사용하지 않아서 발생하는 경고
~ varargs : 가변인자의 타입이 지네릭 타입일 때 발생하는 경고
@SuppressWarnings("unchecked")
ArrayList list = new ArrayList();
list.add(obj);
@SuppressWarnings({"deprecation", "unchecked", "varargs"})
// 메타 애너테이션
- 애너테이션을 위한 애너테이션
- import static java.lang.annotation;
@Target : 애너테이션을 정의할 때, 적용대상 지정에 사용.
~ ANNOTATION_TYPE : 애너테이션
~ CONSTRUCTOR : 생성자
~ FIELD : 필드(멤버 변수, enum 상수)
~ LOCAL_VARIABLE : 지역 변수
~ METHOD : 메서드
~ PACKAGE : 패키지
~ PARAMETER : 매개변수
~ TYPE : 타입(클래스, 인터페이스, enum)
~ TYPE_PARAMETER : 타입 매개변수
~ TYPE_USE : 타입이 사용되는 모든 곳
- import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.*;
@Target({FIELD, TYPE, TYPE_USE})
public @interface MyAnnotation {}
@MyAnnotation // 적용 대상이 TYPE인 경우
class MyClass {
@MyAnnotation // 적용 대상이 FIELD인 경우
int i;
@MyAnnotation // 적용 대상이 TYPE_USE인 경우
MyClass mc;
}
@Retention : 애너테이션이 유지되는 기간을 지정하는 데 사용.
~ SOURCE : 소스 파일에만 존재. 클래스 파일에는 존재하지 않음.
~ RUNTIME : 클래스 파일에 존재. 실행 시에 사용 가능.
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Rentention(RententionPolicy.SOURCE)
public @interface Override {}
@Documented : javadoc으로 작성한 문서에 포함할 때 사용.
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Documented
@Rentetion(RententionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface{}
@Inherited : 애너테이션을 자손 클래스에 상속할 때 사용.
import java.lang.annotation.Inherited
@Inherited
@interface SuperAnno {}
@SuperAnno
class Parent{}
class Child extends Prent{} // Child에 애너테이션이 붙은 것으로 인식
@Repeatable : 반복해서 붙일 수 있는 애너테이션을 정의할 때 사용.
import java.lang.annotation.Repeatable;
@Repeatable()
@interface ToDo{
String value();
}
@ToDo("delete test codes.")
@ToDO("override inherited methods")
class My class {
...
}
// 애너테이션 정의
@interface 애너테이션명 {
타입 요소이름(); //애너테이션의 요소 선언
...
}
- 애너테이션의 메서드는 추상 메서드이며, 애너테이션을 적용할 때 지정함.(순서x)
@interface TestInfo {
int count();
String testedBy();
String[] testTools();
String[] testTools();
TestType testType();
DateTime testDate();
}
@TestInfo(
count = 3, testedBy = "Han",
testTools = {"JUnit", "AutoTester"},
testType = TestType.FIRST,
testDate = @DateTime(yymmdd = "221217", hhmmss = "231848")
)
public class NewClass { ... }
- 요소가 하나이고 이름이 value일 때는 요소 이름 생략 가능.
- 적용 시 값을 지정하지 않으면 사용될 수 있는 기본값 지정 가능.(null 제외)
- 요소의 타입이 배열인 경우, 괄호{}를 사용해야 한다.(값이 없을 때, 값이 여러 개 일 때)
- Annotation은 모든 애너테이션의 조상이지만 상속은 불가.(Annotation은 인터페이스!)
- 애너테이션 요소 선언 시 지켜야 하는 규칙
① 요소의 타입은 기본형, String, enum, 애너테이션, Class만 허용된다.
② 괄호() 안에 매개변수를 선언할 수 없다.
③ 예외를 선언할 수 없다.
④ 요소를 타입 매개변수로 정의할 수 없다.
// 마커 애너테이션 : 요소가 하나도 정의되지 않은 애너테이션
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {} // 마커 애너테이션
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Test {} // 마커 애너테이션
'자바(JAVA)' 카테고리의 다른 글
[자바(Java)] 람다식 (0) | 2022.12.20 |
---|---|
[자바(Java)] 쓰레드(Thread) (0) | 2022.12.18 |
[자바(Java)] 열거형(enum) (0) | 2022.12.17 |
[자바(Java)] 제네릭(Generics) (1) | 2022.12.17 |
[자바(Java)] Collections (0) | 2022.12.16 |