[Java] 애너테이션

Minit88·2023년 3월 7일
0

[Java]

목록 보기
14/18
post-thumbnail

에너테이션

에너테이션은 주석과 기능적으로 비슷하다. 주석을 통해 코드에 대한 정보를 제공할 수 있듯, 에너테이션도 정보 전달을 위한 목적으로 만들어진 문법 요소이다.

주석은 개발자 즉, 사람에게 정보를 전달하는 기능을 담당하는 반면에 에너테이션은 다른 프로그램에게 정보를 전달한다.
아래 예시를 통해 에너테이션에 대해 알아보자.

먼저 ExampleOfInterface01 이라는 인터페이스를 생성하고 그 밑에 void 타입의 ' example ' 추상메서드를 선언한다.

그리고 위 인터페이스를 구현할 클래스를 선언하고 그 밑에 example() 메서드를 구현하게 되면, Annotate as @Override 라는 항목이 뜨게 된다.

클릭하게 되면 @Override 가 생성되고 이것은 에너테이션에 해당한다.

이처럼 에너테이션은 컴파일러 또는 다른 프로그램에게 필요한 정보를 제공해주는 역할을 한다.

에너테이션의 종류

에너테이션에는 JDK가 기본적으로 제공하는 에너테이션도 있지만, 다른 프로그램에서 제공하는 에너테이션도 있다..

JDK에서 기본적으로 제공하는 에너테이션은 두 가지로 구분된다.

  • 표준 에너테이션 : JDK에 내장되어 있는 일반적인 에너테이션이다.
  • 메타 에너테이션 : 다른 에너테이션을 정의할 때 사용하는 에너테이션이다.

표준 에너테이션

가장 빈번하게 사용되는 네가지 중심으로 간략히 살펴보면,

@Override

@Override 는 메서드 앞에만 붙일 수 있는 에너테이션으로, 선언한 메서드가 상위 클래스의 메서드를 오버라이딩하거나 추상 메서드를 구현하는 메서드라는 것을 컴파일러에게 알려주는 역할을 수행한다.

컴파일러 과정에서 컴파일러가 @Override 를 발견하면, @Override가 붙은 메서드와 동일한 이름을 가진 메서드가 상위 클래스(또는 인터페이스)에 존재하는지 검사한다.

위 경우를 예시로 들면, Example01에서 구현한 example 메서드에서의 @Override 는 상위 인터페이스 'ExampleOfInterface01' 에서 example 메서드를 검사하게 된다.

@Override 를 붙이지 않아 컴파일러는 기존 메소드를 참조하는 것이 아닌 새로운 메서드를 정의하는 것으로 간주하고, 에러를 발생시키지 않게 되어, 이때 컴파일 에러 없이 코드가 실행되게 되면, 실행 시에 런타임 에러가 발생할 수 있게 되어 어디서 에러가 발생했는 지를 찾아내기 어려워 진다.

Deprecated

@Deprecated 는 기존에 사용하던 기술이 다른 기술로 대체되어 기존 기술을 적용한 코드를 더 이상 사용하지 않도로 유도하는 경우에 사용

class OldClass {
	@Deprecated
	private int oldField;

	@Deprecated
	int getOldField() { return oldField; }
}

위 예시를 보면 OldClass의 olfField 와에 getOldField에 @Deprecated가 붙어 있다.


다른 클래스에서 OldClass를 인스턴스화하여 getOldField() 를 호출하면 위와 같이 취소선이 뜨면서 인텔리제이가 경고 메시지를 출력해준다.

SuppressWarnings

SuppressWarnings 에너테이션은 컴파일 경고 메시지가 나타나지 않도록 한다. 아래와 같이 @SuppressWarnings 뒤에 괄호를 붙이고 그 안에 억제하고자 하는 경고메세지를 지정해줄 수 있다.

@SuppressWarnings({"deprecation", "unused", "null"})

위 같은 방식으로 여러 개의 경고 유형을 나열 가능하다

@FunctionalInterface

함수형을 선언할 때, 컴파일러가 함수형 인터페이스의 선언이 바르게 선언되었는지 확인하도록 한다. 바르게 선언되지 않은 경우, 에러를 발생시킨다.

@FunctionalInterface
public interface ExampleInterface {
	public abstract void example(); // 단 하나의 추상 메서드
}

메타 에너테이션

대표적인 메타 에너테이션 몇 가지를 살표보면

@Target

@Target 에너테이션은 이름 그대로 에너테이션을 적용할 "대상"을 지정하는 데 사용된다.


[그림] 에너테이션을 사용하여 지정할 수 있는 대상의 타입

import static java.lang.annotation.ElementType.*; 
//import문을 이용하여 ElementType.TYPE 대신 TYPE과 같이 간단히 작성할 수 있습니다.

@Target({FIELD, TYPE, TYPE_USE})	// 적용대상이 FIELD, TYPE
public @interface CustomAnnotation { }	// CustomAnnotation을 정의

@CustomAnnotation	// 적용대상이 TYPE인 경우
class Main {
    
		@CustomAnnotation	// 적용대상이 FIELD인 경우
    int i;
}

@Documented

@Documented 에너테이션은 에너테이션에 대한 정보가 javadoc으로 작성한 문서에 포함되도록 하는 에너테이션 설정이다.

자바에서 제고하는 표준 에너테이션과 메타 에너테이션 중 @Override , @SuppressWarnings 을 제외하고는 모두 @Documented가 적용되어 있다.

@Documented
@Target(ElementType.Type)
public @interface CustomAnnotation { }

Inherited

@Inherited 애너테이션은 이름에서도 알 수 있듯이 하위 클래스가 애너테이션을 상속받도록 한다. @Inherited 애너테이션을 상위 클래스에 붙이면, 하위 클래스도 상위 클래스에 붙은 애너테이션들이 동일하게 적용된다.

@Inherited // @SuperAnnotation이 하위 클래스까지 적용
@interface SuperAnnotation{ }

@SuperAnnotation
class Super { }

class Sub extends Super{ } // Sub에 애너테이션이 붙은 것으로 인식

Retention

특정 에너테이션의 지속 시간을 결정하는 데 사용한다. 에너테이션과 관련한 유지 정책의 종류에는 다음의 세 가지가 있다.

유지 정책이란 에너테이션이 유지되는 기간을 지정하는 속성이다.

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE) 
//오버라이딩이 제대로 되었는지 컴파일러가 확인하는 용도 
//클래스 파일에 남길 필요 없이 컴파일시에만 확인하고 사라짐
public @interface Override(){ }

@Repeatable

에너테이션을 여러 번 붙일 수 있도록 허용한다는 의미를 가짐

@Repeatable(Works.class) // Work 애너테이션을 여러 번 반복해서 쓸 수 있게 한다.  
@interface Work{  
    String value();  
}

사용자 타입이 에너테이션 Work를 정의하고 @Repeatable에너테이션을 사용하여 이것을 여러번 사용할 수 있도록 한 후에,

@Work("코드 업데이트")  
@Work("메서드 오버라이딩")  
class Main{  
	... 생략 ...
}

work 에너테이션을 하나의 대상에 여러번 적용하는 것이 가능해졌다.

사용자 정의 에너테이션

사용자 정의 애너테이션은 이름 그대로 사용자가 직접 애너테이션을 정의해서 사용하는 것을 의미

@interface 애너테이션명 { // 인터페이스 앞에 @기호만 붙이면 애너테이션을 정의할 수 있습니다. 
	타입 요소명(); // 애너테이션 요소를 선언
}

애너테이션은 java.lang.annotation 인터페이스를 상속받기 때문에 다른 클래스나 인터페이스를 상속 받을 수 없다

profile
" To be BE "

0개의 댓글