과거에는 소스코드와 문서를 따로 관리하였는데 서로 간의 불일치가 발생하였다. 이를 해결하기 위해 소스코드와 문서를 하나로 합치는 javadoc.exe를 만들었다.
'/**'
로 시작하는 주석 안에 소스코드에 대한 설명들이 있고 '@'
이 붙은 태그가 있는데 이를 애너테이션이라고 한다. 애너테이션은 주석처럼 프로그래밍 언어에 영향을 미치지 않으면서 유용한 정보를 제공한다.
컴파일러에게 유용한 정보를 제공한다.
@Override
class Child extends Parent {
@Override
void parentMethod()
}
@Deprecated
@Duprecated
를 사용하는데 이를 사용할 경우 컴파일 시 경고 메시지가 출력된다.class NewClass {
@Deprecated
int oldField;
@Deprecated
int getOldField(){
return oldField;
}
}
@SuppressWarnings
@SuppressWarnings("unchecked")
@FunctionalInterface
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
새로운 애너테이션을 정의할 때 애너테이션의 적용대상이나 유지기간 등을 지정하는데 사용된다.
@Target
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VAIABLE})
@Retention
Documented
@Inherited
@Inherited // @SupperAnno가 자식까지 영향 미침
@interface SupperAnno {}
@SuperAnno
class Parent {}
class Child extends Parent {} // Child에 애너테이션이 붙은 것으로 인식
@Repeatable
@interface 애너테이션이름 {
타입 요소이름();
}
애너테이션 내에 선언된 메서드를 애너테이션의 요소라고 한다. 요소는 반환값이 있고 매개변수는 없는 추상 메서드의 형태를 가지며 구현하지 않아도 된다.
<T>
로 정의불가package ch12.AnnotationEx5;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Deprecated
@SuppressWarnings("1111") // 유효하지 않은 애너테이션 무시됨
@TestInfo(testedBy = "aaa", testDate = @DateTime(yymmdd = "161601", hhmmss = "235959"))
public class AnnotationEx5 {
public static void main(String[] args) {
// AnnotationEx5클래스에 적용된 애너테이션을 실행시간에 얻으려면 AnnotationEx5의 Class 객체를 얻는다.
// 모든 클래스 파일은 클래스로더에 의해 메모리에 올라갈 때 클래스에 대한 정보가 담긴 객체를 생성하는데 이를 클래스 객체라고 한다.
Class<AnnotationEx5> cls = AnnotationEx5.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);
}
}
}
@Retention(RetentionPolicy.RUNTIME) // 실행 시에 사용가능
@interface TestInfo {
int count() default 1;
String testedBy();
String[] testTools() default "JUnit";
TestType testType() default TestType.FIRST; // enum TestType {FIRST, FINAL}
DateTime testDate(); // 자신이 아닌 다른 애너테이션 포함 가능
}
@Retention(RetentionPolicy.RUNTIME)
@interface DateTime {
String yymmdd();
String hhmmss();
}
enum TestType {FIRST, FINAL}