공부/Java

[Java-12] 애너테이션(Annotation)

줭♪(´▽`) 2021. 7. 2. 16:32

1. 애너테이션(Annotation)이란?

- 주석(comment)처럼 프로그래밍 언어에 영향을 미치지 않으면서, 다른 프로그램에게 유용한 정보 제공

 

2. 표준 애너테이션

- 자바에서 기본적으로 제공하는 애너테이션

- 주로 컴파일러에게 유용한 정보 제공

 

@Override 컴파일러에게 오버라이딩하는 메서드라는 것을 알림
@Deprecated 앞으로 사용하지 않을 것을 권장함
@SuppressWarnings 컴파일러의 특정 경고메시지가 나타나지 않게 해줌
@SafeVarargs 지네릭스 타입의 가변인자에 사용 (JDK1.7)
@FunctionalInterface 함수형 인터페이스라는 것을 알림 (JDK1.8)
@Native native메서드에서 참조되는 상수 앞에 붙임(JDK1.8)

 

 

① @Override

- 메서드 앞에만 붙임

- 조상의 메서드를 오버라이딩한 것이라는 걸 컴파일러에게 알려줌

- 같은 이름의 메서드가 조상에 있는지 확인하고, 없으면 에러메시지 출력

- 입력 실수를 미연에 방지하므로 필수는 아니지만 명시해주는 것이 좋음

 

② @Deprecated

- 더 이상 사용되지 않는 필드나 메서드에 붙임

- 다른 것으로 대체되었으니 더 이상 사용하지 않을 것을 권한다는 의미

 

③ @FunctionalInterface

- 함수형 인터페이스(functional interface)를 선언할 때 붙임

- 함수형 인터페이스를 올바르게 선언했는지 확인하고, 잘못된 경우 에러를 발생시킴

 

④ @SuppressWarnings

- 컴파일러의 경고메시지를 보이지 않게 억제시킴

- 억제하려는 경고 메시지를 괄호 안에 문자열로 지정

 

@SuppressWarnings("unchecked")		// 지네릭스 관련 경고 억제
ArrayList list = new ArrayList();	// 지네릭 타입을 지정하지 않음
list.add(obj);		// 경고 발생

// 둘 이상의 경고 동시 억제 가능
@SuppressWarnings({"deprecation", "unchecked", "varargs"})

 

 

⑤ @SafeVarargs

- 메서드에 선언된 가변인자의 타입이 non-reifiable타입일 경우, unchecked 경고 발생

- 이를 억제하기 위해 사용

 

가변인자(Varargs, variable arguments)
- 매개변수의 개수를 동적으로 지정해줄 수 있음
- JDK1.5부터 사용
- '타입...변수명'의 형태로 사용
- 내부적으로 배열을 생성해서 사용함
- 빈 인자값, 같은 타입의 배열 인자값 가능
- 매개변수가 여러개라면 가변인자는 항상 마지막에 선언해야 함

 

non-reifiable 타입 : 컴파일 후에 제거되어 런타임 시에는 타입 정보를 알 수 없음 (지네릭 타입)
reifiable 타입 : 컴파일 후에도 제거되지 않아 런타임 시에 타입 정보를 알 수 있음

 

public static <T> List<T> asList(T... a) {
    return new ArrayList<T>(a);	// ArrayList(E[] array)를 호출, 경고 발생
}

-> 가변인자인 동시에 지네릭 타입

-> 컴파일러가 체크하여 타입 T가 아닌 다른 타입이 들어가지 못하게 함으로 안전함

-> @SafeVarargs로 이 메서드의 가변인자는 타입 안전성이 있다고 컴파일러에게 알림

-> @SafeVarargs로 unchecked 경고는 억제 가능하지만 varargs 경고는 억제 불가능

-> @SupressWarnings("varargs")를 같이 붙여 해결함

 

@SafeVarargs			// 'unchecked' 경고 억제
@SuppressWarning("varargs")	// 'varargs' 경고 억제
public static <T> List<T> asList(T... a) {
    return new ArrayList<T>(a);	// ArrayList(E[] array)를 호출, 경고 발생
}

 

 

3. 메타 애너테이션

- 애너테이션을 위한 애너테이션

- 애너테이션을 정의할 때 애너테이션의 적용대상(target)이나 유지기간(retention) 등을 지정하는데 사용

 

@Target 애너테이션이 적용가능한 대상을 지정하는데 사용
@Documented 애너테이션 정보가 javadoc으로 작성된 문서에 포함되게 함
@Inherited 애너테이션이 자손 클래스에 상속되게 함
@Retention 애너테이션이 유지되는 범위를 지정하는데 사용
@Repeatable 애너테이션을 반복해서 적용할 수 있게 함(JDK1.8)

 

 

① @Target

- 애너테이션이 적용가능한 대상 지정

- 여러 개의 값을 지정할 때는 배열처럼 { } 사용

- 지정할 수 있는 애너테이션 적용대상의 종류 : ANNOTATION_TYPE, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE, TYPE_PARAMETER, TYPE_USE

 

② @Retention

- 애너테이션이 유지(retention)되는 기간을 지정

- RetentionPolicy.SOURCE : 소스 파일에만 존재, 클래스 파일에는 존재X

- RetentionPolicy.CLASS : 클래스 파일에 존재, 실행시에 사용불가, 기본값

- RetentionPolicy.RUNTIME : 클래스 파일에 존재, 실행시에 사용가능

 

③ @Documented

- 애너테이션에 대한 정보가 javadoc으로 작성한 문서에 포함되도록 함

- @Override, @SuppressWarnings을 제외하고 모두 붙어있음

 

④ @Inherited
- 애너테이션이 자손 클래스에 상속되도록 함

- 애너테이션을 조상 클래스에 붙이면, 자손 클래스도 이 애너테이션이 붙은 것과 같이 인식됨

 

⑤ @Repeatable

- 보통 하나의 대상에 한 종류의 애너테이션이 붙지만, @Repeatable을 붙이면 여러 번 붙일 수 있음

 

⑥ @Native

- 네이티브 메서드(native method)에 의해 참조되는 '상수 필드(constant field)'에 붙이는 애너테이션

 

 

4. 애너테이션 타입 정의하기

 

@interface 애너테이션이름 {
    타입 요소이름();
    ...
}

 

 

1) 애너테이션의 요소(element)

- 애너테이션 내에 선언된 메서드

- 추상 메서드의 형태(반환값이 있고 매개변수는 없음)

- 상속을 통해 구현하지 않아도 됨

- 단, 애너테이션 적용 시 요소들의 값을 빠짐없이 지정해줘야 함 (순서는 상관 X)

 

- 기본값을 가질 수 있고, 값을 지정하지 않으면 기본값이 사용됨

@interface TestInfo {
    int count() default 1;
}

@TestInfo		// @TestInfo(count=1)와 동일
public class NewClass { ... }

 

2) java.lang.annotation.Annotation

- 모든 애너테이션의 조상

- 애너테이션은 상속이 허용되지 않으므로 명시적으로 Annotation을 조상으로 지정할 수 없음

- Annotation은 애너테이션이 아닌 일반 인터페이스로 정의되어 있음

- 따라서 모든 애너테이션 객체는 equals(), hashCode(), toString()과 같은 메서드를 호출할 수 있음

 

3) 마커 애너테이션(Marker Annotation)

- 요소가 하나도 정의되지 않은 애너테이션

- ex) Serializable, Cloneable

 

4) 애너테이션 요소의 규칙

- 요소의 타입은 기본형, String, enum, 애너테이션, Class만 허용

- ()안에 매개변수를 선언할 수 없음

- 예외를 선언할 수 없음

- 요소를 타입 매개변수로 정의할 수 없음

 

@interface AnnoTest {
    int id = 100;			// O, 상수 선언
    String major(int i, int j);		// X, 매개변수 선언 불가
    String minor() throws Exception;	// X, 예외 선언 불가
    ArrayList<T> list();		// X, 요소의 타입에 타입 매개변수 불가
}

 

 

 

 

 

 

참고 - Java의 정석 3rd Edition (저자 : 남궁성, 출판 : 도우출판)

'공부 > Java' 카테고리의 다른 글

[Java-14] 람다식(Lambda expression)  (0) 2021.07.06
[Java-13] 쓰레드(Thread)  (0) 2021.07.06
[Java-12] 열거형(Enums)  (0) 2021.07.02
[Java-12] 지네릭스(Generics)  (0) 2021.07.02
[Java] BufferedReader와 BufferedWriter  (0) 2021.06.13