[자바의 정석 - 기초편] ch12-23~26 표준애너테이션
package test;
class Parent {
void parentMethod() {
}
}
class Child extends Parent {
@Override
@Deprecated
void parentMethod() {
}
}
@FunctionalInterface // 함수형 인터페이스는 하나의 추상 메서드만 가능
interface Testable {
void test(); // 추상 메서드
// void check(); // 추상 메서드
}
public class Test {
public static void main(String[] args) {
Child c = new Child();
c.parentMethod(); // deprecated된 메서드 사용
}
}
@Deprecated
앞으로 사용하지 않을 것을 권장하는 필드나 메서드에 붙인다.
ex) Date 클래스의 getDate()
@FunctionalInterface
함수형 인터페이스에 붙이면, 컴파일러가 올바르게 작성했는지 체크
함수형 인터페이스에는 하나의 추상메서드만 가져야 한다는 제약이 있음
package test;
class Parent {
void parentMethod() {
}
}
class Child extends Parent {
@Override
@Deprecated
void parentMethod() {
}
}
@FunctionalInterface
interface Testable {
void test();
// void check();
}
public class Test {
@SuppressWarnings("deprecation") // 추가
public static void main(String[] args) {
Child c = new Child();
c.parentMethod();
}
}
@SuppressWarnings
컴파일러 경고메시지가 나타나지 않게 억제한다.
[자바의 정석 - 기초편] ch12-29~33 메타애너테이션
메타 애너테이션 : 애너테이션을 위한 애너테이션
java.lang.annotation패키지에 포함
@Target
애너테이션을 정의할 때, 적용대상 지정에 사용
@Target({TYPE, FIELD, TYPE_USE}) // 적용대상이 TYPE, FIELD, TYPE_USE
public @interface MyAnnotation { } // MyAnnotation을 정의
@MyAnnotation // 적용대상이 TYPE인 경우
class MyClass {
@MyAnnotation // 적용대상이 FIELD인 경우
int i;
@MyAnnotation // 적용대상이 TYPE_USE인 겅우
MyClass mc;
}
@Retention
애너테이션이 유지(retention)되는 기간을 지정하는데 사용
유지 정책 | 의미 |
SOURCE | 소스 파일에만 존재. 클래스파일에는 존재하지 않음 |
CLASS | 클래스 파일에 존재. 실행시에 사용불가. 기본값 |
RUNTIME | 클래스 파일에 존재. 실행시에 사용가능. |
ex)
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface() {}
@Documented
javadoc으로 작성한 문서에 포함시킬 때 사용
@Inherited
애너테이션을 자손 클래스에 상속하고자 할 때 사용
@Inherited
@interface SuperAnno {}
@SuperAnno
class Parent {}
// @SuperAnno 가 붙은 것으로 인식
class Child extends Parent {}
@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이어야 함
}
[자바의 정석 - 기초편] ch12-34~37 애너테이션 타입 정의하기, 애너테이션의 요소
애너테이션 타입 정의하기
- 애너테이션을 직접 만들어 쓸 수 있다.
@interface 애너테이션이름 {
타입 요소이름(); // 애너테이션의 요소를 선언 / 추상 메서드, 애너테이션을 적용할 때 지정(순서X)
...
}
- 애너테이션의 메서드는 추상 메서드이며, 애너테이션을 적용할 때 지정(순서X)
enum TestType {FIRST, FINAL}
@interface DateTime {
String yymmdd(); // day
String hhmmss(); // time
}
@interface TestInfo {
int count();
String testedBy();
String[] testTools();
TestType testType(); // enum TestType {FIRST, FINAL}
DateTime testDate(); // 자신이 아닌 다른 애너테이션(@DateTime)을 포함할 수 있다.
}
// 순서X
@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;
}
@TestInfo // @TestInfo(count=1)과 동일
public class NewClass { ... }
- 요소가 하나이고 이름이 value일 때는 요소의 이름 생략가능
@interface TestInfo {
String value();
}
@TestInfo("passed") // @TestInfo(value="passed")와 동일
class NewClass { ... }
- 요소의 타입이 배열인 경우, 괄호{}를 사용해야 한다.
@interface TestInfo {
String[] testTools();
}
@TestInfo(testTools = {"JUnit", "AutoTester"})
@TestInfo(testTools = "JUnit")
@TestInfo(testTools = {}) // 값이 없으 때는 괄호{}가 반드시 필요
모든 애너테이션의 조상(인터페이스)
public interface Annotation {
boolean equals(Object obj);
int hashCode();
String toString();
Class<? extends Annotation> annotationType();
}
마커 애너테이션
- 요소가 하나도 정의되지 않은 애너테이션
public @interface Override {} // 마커 애너테이션. 정의된 요소가 하나도 없다.
public @interface Test {} // 마커 애너테이션. 정의된 요소가 하나도 없다.
@Test // 이 메서드가 테스트 대상임을 테스트 프로그램에게 알린다.
public void method() {
...
}
애너테이션 요소의 규칙
- 요소의 타입은 기본형, String, enum, 애너테이션, Class만 허용된
- 괄호() 안에 매개변수를 선언할 수 없다.
- 예외를 선언할 수 없다.
- 요소를 타입 매개변수로 정의할 수 없다.
@interface AnnoTest {
int id = 100;
String major(int i, int j); // 매개변수 불가능 : (int i, int j)
String minor() throws Exception; // 예외 불가능 : throws Exception
ArrayList<T> list(); // 요소를 타입 매개변수로 정의X : <T>
}
실습
enum TestType {FIRST, FINAL}
@interface DateTime {
String yymmdd(); // day
String hhmmss(); // time
}
@Retention(RetentionPolicy.RUNTIME)
@interface TestInfo {
int count() default 1;
String testedBy();
String[] testTools() default "JUnit";
TestType testType() default TestType.FIRST;
DateTime testDate();
}
@Deprecated
@SuppressWarnings("1111") // 유효하지 않은 애너테이션은 무시된다.
@TestInfo(testedBy = "aaa",
testTools = {"JUnit", "JUnit5"},
testDate = @DateTime(yymmdd = "160101", hhmmss = "235959")
)
public class Test {
public static void main(String[] args) {
// AnnotaionEx5의 Class객체를 얻는다.
Class<Test> cls = Test.class;
TestInfo anno = (TestInfo)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();
// AnnotationEx5에 적용된 모든 애너테이션을 가져온다.
Annotation[] annoArr = cls.getAnnotations();
for(Annotation a : annoArr)
System.out.println(a);
}
}
결과
참고
[자바의 정석 - 기초편]
https://www.youtube.com/watch?v=7eX1EB76Dio&list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&index=145&ab_channel=%EB%82%A8%EA%B6%81%EC%84%B1%EC%9D%98%EC%A0%95%EC%84%9D%EC%BD%94%EB%94%A9
https://www.youtube.com/watch?v=7eX1EB76Dio&list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&index=145&ab_channel=%EB%82%A8%EA%B6%81%EC%84%B1%EC%9D%98%EC%A0%95%EC%84%9D%EC%BD%94%EB%94%A9
https://www.youtube.com/watch?v=p7KStWk8hWU&list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&index=146&ab_channel=%EB%82%A8%EA%B6%81%EC%84%B1%EC%9D%98%EC%A0%95%EC%84%9D%EC%BD%94%EB%94%A9
https://www.youtube.com/watch?v=81U0MyuZQKo&list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&index=147&ab_channel=%EB%82%A8%EA%B6%81%EC%84%B1%EC%9D%98%EC%A0%95%EC%84%9D%EC%BD%94%EB%94%A9
'개발 관련 강의 정리 > 자바의정석' 카테고리의 다른 글
[자바의 정석] 스트림 정리 (0) | 2023.07.10 |
---|---|
[자바의 정석 - 기초편] 람다 정리 (0) | 2023.04.20 |
댓글