@Override
public void method(){
}
이 메서드가 재정의 됐음을 알려준다. 메서드 자체에는 영향을 미치지 않음.
@Override
의 API@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
@Target(ElementType.METHOD)
-> 타겟이 Enum상수로 정의되어 있다. 적용대상을 나타냄
@Retention(RetentionPolicy.SOURCE)
-> 시점에 대한 애너테이션. 애너테이션이 유지되는 기간
@Retention(RetentionPolicy.SOURCE)
의 APIpublic enum RetentionPolicy {
SOURCE, // 소스 파일에만 존재, 클래스 파일 존재X -> 컴파일 시점에 정보가 전달됨, 컴파일 이후에 제거
CLASS, // 자바코드에 존재(java), 클래스 파일에 존재(class) -> 디폴트값, 정보전달X(거의 사용X)
RUNTIME // 자바코드에 존재(java), 클래스 파일에 존재(class) -> 실행 중에 정보가 전달(많이 사용)
}
@Documented
: 애너테이션에 대한 정보가 javadoc으로 작성한 문서에 포함되도록 한다.
표준 애너테이션
@Deprecated
: 다른 것으로 대체되었으니 더 이상 사용하지 않을 것을 권한다는 의미@FunctionalInterface
: '함수형 인터페이스(functional interface)'를 선언할 때, 이 애너테이션을 붙이면 컴파일러가 '함수형 인터페이스'를 올바르게 선언했는지 확인하고, 잘못된 경우 에러를 발생@SupressWarnings
: 컴파일러가 보여주는 경고메시지가 나타나지 않게 억제해 준다.deprecation
: "@Deprecated"가 붙은 대상을 사용해서 발생하는 경고를 억제unchecked
: 지네릭스로 타입을 지정하지 않았을 때 발생하는 경고를 억제rawtypes
: 지네릭스를 사용하지 않아서 발생하는 경고를 억제varargs
: 가변인자의 타입이 제네릭 타입일 때 발생하는 경고를 억제둘 이상의 경고를 억제할 땐 배열로 정의
@SupressWarnings({...})
@SafeVarags
이 애너테이션은 static이나 final이 붙은 메서드에만 붙일 수 있다. 즉 오버라이드 될 수 있는 메서드에는 사용할 수 없다.
non-reifiable
타입 이란?지네릭스에서 살펴본 것과 같이 어떤 타입들은 컴파일 이후에 제거된다.
컴파일 후에도 제거되지 않는 타입을 reifiable타입이라 하고, 제거되는 타입을 non-reifiable타입이라고 한다.
지네릭 타입들은 대부분 컴파일 시에 제거되므로 non-reifiable타입이다.
값을 지정할 필요가 없는 경우, 애너테이션의 요소를 하나도 정의하지 않을 수 있다. Serializable이나 Cloneable인터페이스처럼, 요소가 하나도 정의되지 않은 애너테이션을 마커 애너테이션이라고 한다.
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
public @interface Myannotation {
String value(); // 추가적인 정보 전달 설정가능
}
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Myannotation2 {
String value() default "기본값"; // 디폴트값 설정 가능
int[] nums();
}
package annotation;
import java.util.Arrays;
@Myannotation(value = "값")
public class MyClass {
@Myannotation(value = "값")
int num;
@Myannotation(value = "값")
public int add(int ... num){
return Arrays.stream(num).sum();
}
}
package annotation;
import java.util.Arrays;
// @Myannotation2(value ="값", nums = {1, 2, 3})
@Myannotation2(nums = {1, 2, 3})
public class Myclass2 {
public static void main(String[] args) {
Class cls = Myclass2.class;
Myannotation2 anno = (Myannotation2) cls.getAnnotation(Myannotation2.class);
String value = anno.value();
System.out.println(value);
int[] nums = anno.nums();
System.out.println(Arrays.toString(nums));
}
// @Myannotation2(nums = {1,2,3})
// public static int add(int ... a){
// return Arrays.stream(a).sum();
// }
}