Ch12-34~37. 애너테이션
0. 목차
Chapter12. 지네릭스, 열거형, 애너테이션
Ch12 - 34. 애너테이션 타입 정의하기
Ch12 - 35. 애너테이션의 요소
Ch11 - 36. 모든 애너테이션의 조상
Ch11 - 37. 마커 애너테이션
Ch11 - 38. 애너테이션 요소의 규칙
Ch11 - 39. 애너테이션의 활용 예제
Ch12 - 34. 애너테이션 타입 정의하기
▶ 애너테이션을 직접 만들어 사용 가능
▷ 애너테이션 생성 방법
@interface 애너테이션 이름 {
타입 요소 이름(); // 애너테이션 요소 선언
...
}
- @DateTime의 예
@interface DateTime { String yymmdd(); String hhmmss(); }
▷ 애너테이션의 메서드는 추상 메서드이며, 애너테이션 적용 시 지정 해 줌(순서X)
- @TestInfo 생성
@interface TestInfo { int count(); String testedBy(); String[] testTools(); TestType testType(); // enum TestType { FIRST, FINAL } DateTime testDate(); // 자신이 아닌 다른 애너테이션(@DateTime) 포함 가능 }
- @TestInfo 사용
@TestInfo ( count = 3;, testedBy = "Baek", testTools = {"JUnit", "AutoTester"}, testType = TestType.FIRST, testDate = @DateTime(yymmdd = "160101", hhmmss = "235959") ) // 요소마다 값을 지정 public class NesClass { ... }
- 추상 메서드를 구현할 필요X
- 사용할 때 요소마다 값을 넣어주면 됨
- 추상 메서드를 구현할 필요X
Ch12 - 35. 애너테이션의 요소
▶ 애너테이션 요소 지정
▷ 적용 시 값을 지정하지 않으면, 사용될 수 있는 기본값 지정가능
@interface TestInfo {
int count() default 1; // 기본값을 1로 지정
}
@TestInfo // @TestInfo(count = 1)과 동일
public class NewClass { ... }
- @TestInfo 사용 시, 요소 지정 해야하지만 default가 있기 때문에 요소 지정 생략
▷ 요소가 하나이고 이름이 value일 때, 요소 이름 생략 가능
@interface TestInfo {
String value();
}
@TestInfo("passed") // @TestInfo(value = "passed")와 동일
public class NewClass { ... }
▷ 요소 타입이 배열인 경우, 괄호{}를 사용해야 함
▷ 단 배열의 값이 하나일 경우 괄호{} 사용하지 않아도 됨
@interface TestInfo {
String[] testTools();
}
// 배열의 값 2개인 경우 : { } 사용
@TestInfo(testTools = ({"Junit", "AutoTester"})
// 배열의 값 1개인 경우 : { } 생략
@TestInfo(testTools = "Junit")
// 배열의 값 0개인 경우 : { } 사용
@TestInfo(testTools = { })
Ch12 - 36. 모든 애너테이션의 조상
▶ java.lang.annotation.Annotation
▷ 모든 애너테이션의 조상
▷ Annotation은 모든 애너테이션의 조상이지만 상속은 불가
@interface TestInfo extends Annotation { // 에러, Annotation 상속 불가
int count();
String testedBy();
}
▷ 사실 Annotation은 인터페이스
package java.lang.annotation;
public interface Annotation { // Annotation 자신은 인터페이스
boolean equals(Object obj);
int hashCode();
String toString();
class<? extends Annotation> annotationType(); // 애너테이션의 타입을 반환
}
- Annotation = 인터페이스 → Annotation의 메서드 = 추상 메서드
- 다른 애너테이션과 달리 추상 메서드를 구현하지 않아도 Annotation 사용 가능
Ch12 - 37. 마커 애너테이션
▶ 마커 애너테이션(Marker Annotation)이란?
▷ 요소가 하나도 정의되지 않은 애너테이션
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override { } // 마커 애너테이션, 정의된 요소가 없음
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Test { } // 마커 애너테이션
@Test // 괄호()에 요소 값 없음, 이 메서드가 테스트 대상임을 테스트 프로그램에게 알림
public void method() { }
Ch12 - 38. 애너테이션 요소의 규칙
▶ 애너테이션의 요소 선언 시, 규칙을 반드시 지켜야 함
▷ 요소의 타입 : 기본형, String, enum, 애너테이션, Class만 허용
▷ 괄호() 안에 매개 변수 선언 불가
▷ 예외 선언 불가
▷ 요소를 타입 매개 변수로 정의 불가
Ch12 - 39. 애너테이션의 활용 예제
▶ Play class를 Deprecated 하기
▷ @Deprecated
@Deprecated
public class Play {
public static void main(String[] args) {
}
}
▶ Play class에 “hello”라는 경고를 억제 시키기
▷ @SuppressWarnings
@Deprecated
@SuppressWarnings("hello") // 경고, 경고 hello는 없으므로 무시
public class Play {
public static void main(String[] args) {
}
}
▶ @TestInfo 생성
▷ @Retention : RUNTIME
@Retention(RetentionPolicy.RUNTIME)
@interface TestInfo {
}
▷ 요소 채우기
@Retention(RetentionPolicy.RUNTIME)
@interface TestInfo {
int count() default 1;
String testedBy();
String[] testTools() default "JUnit";
TestType testType() default TestType.FIRST; // TestType은 enum
DateTime testDate();
}
enum TestType { FIRST, FINAL }
@Retention(RetentionPolicy.RUNTIME)
@interface DateTime {
String yymmdd();
String hhmmss();
}
▶ @TestInfo 사용
▷ 요소에 값 넣어주기
@Deprecated
@SuppressWarnings("hello")
@TestInfo(testedBy="baek", testDate=@DateTime(yymmdd="210806",hhmmss="232323"))
public class Play {
public static void main(String[] args) {
}
}
▶ class의 애너테이션 읽어오는 코드 작성
▷ Play 클래스의 객체 얻어오기
@Deprecated
@SuppressWarnings("hello")
@TestInfo(testedBy="baek", testDate=@DateTime(yymmdd="210806",hhmmss="232323"))
public class Play {
public static void main(String[] args) {
Class<Play> cls = Play.class;
}
}
▷ Play 클래스의 TestInfo 출력
▷ getAnnotation()을 통해 TestInfo 객체 생성
@Deprecated
@SuppressWarnings("hello")
@TestInfo(testedBy="baek", testDate=@DateTime(yymmdd="210806",hhmmss="232323"))
public class Play {
public static void main(String[] args) {
Class<Play> cls = Play.class;
TestInfo anno = cls.getAnnotation(TestInfo.class);
}
}
▷ TestInfo
int count() default 1;
String testedBy();
String[] testTools() default "JUnit";
TestType testType() default TestType.FIRST;
DateTime testDate();
@Deprecated
@SuppressWarnings("hello")
@TestInfo(testedBy="baek", testDate=@DateTime(yymmdd="210806",hhmmss="232323"))
public class Play {
public static void main(String[] args) {
Class<Play> cls = Play.class;
TestInfo anno = cls.getAnnotation(TestInfo.class);
// testedBy()
System.out.println("testedBy : " + anno.testedBy());
// testDate().yymmdd()
System.out.println("testDate().yymmdd() : " + anno.testDate().yymmdd());
// testDate().hhmmss()
System.out.println("testDate().hhmmss() : " + anno.testDate().hhmmss());
// testTools()
for(String str : anno.testTools())
System.out.println("testTools : "+str);
}
}
// console
testedBy : baek
testDate().yymmdd() : 210806
testDate().hhmmss() : 232323
testTools : JUnit
// @TestInfo, TestType, DateTime 설정
@Retention(RetentionPolicy.RUNTIME)
@interface TestInfo {
int count() default 1;
String testedBy();
String[] testTools() default "JUnit";
TestType testType() default TestType.FIRST;
DateTime testDate();
}
enum TestType { FIRST, FINAL }
@Retention(RetentionPolicy.RUNTIME)
@interface DateTime {
String yymmdd();
String hhmmss();
}
▷ 모든 애너테이션 배열에 담아 출력
@Deprecated
@SuppressWarnings("hello")
@TestInfo(testedBy="baek", testDate=@DateTime(yymmdd="210806",hhmmss="232323"))
public class Play {
public static void main(String[] args) {
Class<Play> cls = Play.class;
Annotation[] annoArr = cls.getAnnotations();
for(Annotation a : annoArr)
System.out.println(a);
}
}
// console
@java.lang.Deprecated(forRemoval=false, since="")
@baek.TestInfo(count=1, testType=FIRST, testTools={"JUnit"}, testedBy="baek",
testDate=@baek.DateTime(yymmdd="210806", hhmmss="232323"))
// @TestInfo, TestType, DateTime 설정
@Retention(RetentionPolicy.RUNTIME)
@interface TestInfo {
int count() default 1;
String testedBy();
String[] testTools() default "JUnit";
TestType testType() default TestType.FIRST;
DateTime testDate();
}
enum TestType { FIRST, FINAL }
@Retention(RetentionPolicy.RUNTIME)
@interface DateTime {
String yymmdd();
String hhmmss();
}