어노테이션이란?
어노테이션(Annotation)은 사전적으로는 "주석"이라는 의미를 가지고 있습니다.
자바에서는 @를 이용하여 주석처럼 달아 특수한 의미를 부여해줍니다.
어노테이션은 소스 코드가 컴파일되거나 실행될 때 컴파일러 및 다른 프로그램에게 필요한 정보를 전달해 주는 문법 요소입니다.
어노테이션의 종류
JDK에서 기본적으로 제공하는 어노테이션은 아래의 두 가지로 분류됩니다.
- 표준 어노테이션: 자바에서 기본적으로 제공하는 어노테이션
- 메타 어노테이션: 다른 어노테이션에서도 사용되는 어노테이션을 말하며, custom-annotation을 생성할 때 주로 사용
표준 어노테이션
표준 어노테이션은 자바에서 기본적으로 제공하는 어노테이션입니다.
표준 어노테이션을 여러 가지가 있지만, 그중에서도
- @Override
- @Deprecated
- @SuppressWarning
- @FunctionaIInterface
위의 네 어노테이션이 가장 많이 사용되며, 이를 자세히 알아보도록 하겠습니다.
@Override
@Override 어노테이션은 메서드 앞에 오는 어노테이션입니다.
상위클래스의 메서드를 오버라이딩한다는 것을 컴파일러에게 알리는 역할을 합니다.
그렇다면 @Override 어노테이션을 사용하는 이유는 무엇일까요?
아래의 코드 예제를 보도록 하겠습니다
class SuperClass {
void eat() {...}
}
class SubClass extends UpperClass {
void eta(int a) {...}
// 프로그래머의 오타로 eat을 eta로 입력
}
위의 코드 예제를 보면, 상위 클래스의 메서드를 오버라이딩하려던 중 오타가 발생한 모습입니다.
이러한 경우, 위 예시처럼 @Override를 붙이지 않으면 컴파일러는 eta()라는 새로운 메서드를 정의하는 것으로 간주하여, 에러를 발생시키지 않습니다.
이후 런타임 에러가 발생한다면 어디에서 에러가 발생했는지 에러의 원인을 찾아내기 어려워집니다.
그러나, @Override를 사용하여 eat()이 오버라이딩 메서드라는 것을 컴파일러가 인지하고, 상위 클래스에 eat()이 존재하는지 확인하기 때문에, 이러한 상황을 방지할 수 있습니다.
즉, @Override 메서드를 이용하여 프로그래머의 실수를 방지할 수 있습니다.
아래의 예제 코드는 @Override를 올바르게 사용하는 모습입니다.
class SuperClass {
public void eat() {
...
}
}
class SubClass extends SuperClass{
@Override
public void eat(){
...
}
}
@Deprecated
@Deprecate 어노테이션은 새로운 버전의 JDK가 등장하여 더 이상 사용하지 않는 필드나 메서드가 있을 경우 사용합니다.
즉, @Deprecated 어노테이션은 필드나 메서드가 새로운 것으로 업데이트되었을 때, 기존의 것을 사용하지 않도록 합니다.
따라서 해당 메서드가 하위 버전의 호환성 문제로 삭제하기 곤란하여 남겨두어야만 할 때 @Deprecated 어노테이션을 이용합니다.
아래의 예제 코드를 보도록 하겠습니다
class OldClass {
@Deprecated
private int oldField;
@Deprecated
int getOldField() {
return oldField;
}
}
이처럼 @Deprecated 어노테이션이 있는 메서드를 호출할 때 경고 메시지를 확인할 수 있습니다.
@SuppressWarning
@SuppressWarning 어노테이션은 컴파일 경고 메시지가 나타나지 않도록 합니다.
어노테이션 | 설명 |
@SuppressWarings("all") | 모든 경고를 억제 |
@SuppressWarings("deprecation") | Deprecated 메서드를 사용한 경우에 발생하는 경고를 억제 |
@SuppressWarings("fallthrough") | switch문에서 break 구문이 없을 때 발생하는 경고를 억제 |
@SuppressWarings("finally") | finally와 관련된 경고를 억제 |
@SuppressWarings("null") | null과 관련된 경고를 억제 |
@SuppressWarings("unchecked") | 검증되지 않은 연산자와 관련된 경고를 억제 |
@SuppressWarings("unused") | 사용하지 않는 코드와 관련된 경고를 억제 |
아래의 예제는 여러 개의 경고를 한 번에 묵인하게 할 수 있습니다
@SuppressWarnings({"deprecation","unchecked","null"})
@FunctionaIInterface
@FunctionalInterface 애너테이션은 함수형 인터페이스를 선언할 때, 컴파일러가 함수형 인터페이스의 선언이 바르게 선언되었는지 확인하도록 합니다.
아래의 예제 코드는 @FunctionalInteface를 사용한 코드 예제입니다.
@FunctionalInterface
public interface ExampleInterface {
pulbic abstract void example();
}
함수형 인터페이스에 관한 내용은 람다(Lambda)에서 확인할 수 있습니다
람다에 대한 글은 아래를 확인 부탁드리겠습니다.
메타 어노테이션
메타 어노테이션(meta annotation)은 어노테이션을 정의하는 데 사용되는 어노테이션이라 설명하였습니다.
우선, @Override가 어떻게 정의되어 있는지 확인해 보도록 하겠습니다
@Override의 소스 코드를 보면, 어노테이션을 정의할 때는 @interface 키워드를 사용하여 정의한 것을 확인할 수 있습니다.
또한, 어노테이션 정의부 상단에 @Target, @Retention 애너테이션이 있는 것을 확인할 수 있습니다.
이들은 @Override의 적용 대상과 유지기간을 지정해 주는 역할을 합니다.
위의 @Target과, @Retention은 메타 어노테이션의 대표적인 어노테이션입니다.
위의 어노테이션과 함께 대표적인 어노테이션은 아래와 같습니다.
- @Target
- @Documented
- @Retention
- @Inherited
- @Repeatable
위의 어노테이션을 자세히 알아보도록 하겠습니다.
@Target
@Target 어노테이션은 적용할 "대상"을 지정하는 데 사용합니다.
어노테이션 | 설명 |
ElementType.TYPE | 클래스, 인터페이스, enum |
ElementType.FIELD | 필드 |
ElementType.METHOD | 메서드 |
ElementType.PARAMETER | 파라미터 |
ElementType.CONSTRUCTOR | 생성자 |
ElementType.LOCAL_VARIABLE | 지역 변수 |
ElementType.ANNOTATION_TYPE | 어노테이션 |
ElementType.PACKAGE | 패키지 |
ElementType.TYPE | 클래스, 인터페이스 enum |
ElementType.TYPE_PARAMETER | 타입 파라미터 |
ElementType.TYPE_USE | 타입 |
ElementType.MODULE | 모듈 |
- @Target()의 value로 ElementType을 지정하지 않으면 오류가 납니다.
@Documented
@Documented 어노테이션은 javadoc으로 작성한 문서에 포함되도록 하는 어노테이션 설정입니다.
@Documented
@Target(ElementType.Type)
public @interface CustomAnnotation { }
@Inherited
@Inherited 어노테이션은 하위 클래스가 어노테이션을 상속받도록 합니다.
@Inherited 어노테이션을 상위 클래스에 붙이면, 하위 클래스도 상위 클래스의 어노테이션들이 동일하게 적용됩니다.
@Inherited //@SuperAnnotation이 하위 클래스까지 적용
@interface SuperAnnotation{ }
@SuperAnnotation
class Super { }
class Sub extends Super{ } // Sub class에 어노테이션이 붙은 것으로 인식
위의; 코드 예제를 보면, Super 클래스로부터 확장된 Sub 클래스는 상위 클래스와 동일하게 @SuperAnnotation에 정의된 내용들을 적용받게 됩니다.
@Retention
@Retention 어노테이션은 어노테이션의 지속 시간을 결정하는 데 사용합니다. 어노테이션과 관련한 유지 정책(retention policy)의 종류는 다음 3가지가 있습니다
- SOURCE : 소스 파일에 존재, 클래스파일에는 존재하지 않음
- CLASS : 클래스 파일에 존재, 실행 시에 사용불가, 기본 값
- RUNTIME: 클래스 파일에 존재, 실행시에 사용 가능
@Repeatable
마지막으로, @Repeatable 어노테이션은 어노테이션을 여러 번 붙일 수 있도록 허용한다는 의미를 가지고 있습니다.
예제에서, 사용자 타입의 어노테이션 Work를 정의하고, @Repeatable 어노테이션을 사용하여 이것을 여러 번 사용할 수 있도록 하였습니다
@Repeatable(Work.class)
@interface Work{
String value();
}
@Work("code update")
@Work("method overriding")
class Main {
...
}
'JAVA' 카테고리의 다른 글
[JAVA] 싱글턴 패턴(Singleton pattern) (0) | 2023.03.14 |
---|---|
[JAVA] 한글 깨짐 & error unmappable character (0xEB) for encoding x-windows-949 에러 해결 (0) | 2023.03.13 |
[JAVA] 컬렉션 프레임워크(Collection Framework) - Iterator (6) (0) | 2023.03.11 |
[JAVA] 컬렉션 프레임워크(Collection Framework) - Stack,Queue (5) (0) | 2023.03.11 |
[JAVA] 컬렉션 프레임워크(Collection Framework) - Map <K,V> (4) (2) | 2023.03.10 |