Annotations 이란?
프로그래밍 언어에는 영향을 미치지 않으면서 코드를 프로그램 및 프로그래머에게 정보를 제공. 마치 주석과 유사한 역할을 하는 것을 말한다.
주석이라는 것이 등장하기 전까지는 코드와 문서를 별도로 작성하였고 코드가 변경될 때마다 문서도 함께 변경해줘야 했다고 한다. 하지만 개발자들이 코드만 수정하고 문서는 수정하지 않는 경우가 많았고 이 때문에 코드와 문서가 일치하지 않아 소스코드를 관리하는데 어려움이 많았다고 한다.
이에 대한 해결책으로 코드와 문서를 합치기로 했고 필요한 문서 내용을 코드와 함께 주석으로 작성하고 javadoc.exe 프로그램이 코드 내 주석만 추출하여 문서를 자동으로 만들게 했다.
Annotation이 등장하기 전에는 주석과 유사하게 코드와 대부분 .xml 파일 형태인 설정파일을 따로 작성했고 프로젝트를 여러 사람이 함께 진행할 경우 하나의 .xml 파일을 여러 사람이 사용했기 때문에 사용 및 수정하는데 어려움이 있었다. 이 부분에 대하여 Annotation을 사용하게 되면 각자 자신의 부분에서 필요한 경우 Annotation을 사용하면 어려움을 해결할 수 있다.
예를 들어 @Test 라는 Annotation을 사용하게 되면 해당 부분이 프로그램에는 영향을 미치지 않으면서 작성 부분이 테스트 대상임을 JUnit 단위 테스트 프로그램에게 알리는 역할을 하게 된다.
표준 Annotation
| Annotation | 역할 |
| @Override | 컴파일러에게 오버라이딩하는 Method라는 것을 알림 |
| @Deprecated | 더 이상 사용되지 않아 앞으로 사용하지 말 것을 권장하는 대상에 붙임 |
| @SuppressWarnings | 컴파일러의 특정 경고 메시지가 출력되지 않게 함 |
| @SafeVarargs | 제네릭 타입의 가변인자에 사용 |
| @FunctionsalInterface | 함수형 인터페이스라는 것을 알림 |
| @Native | Native Method에서 참조되는 상수 앞에 붙임 |
| @Target* | Annotation이 적용가능한 대상을 지정하는데 사용 |
| @Documented* | Annotation 정보가 javadoc으로 작성된 문서에 포함되게 함 |
| @Inherited* | Annotation이 자손 클래스에 상속되도록 함 |
| @Retention* | Annotation이 유지되는 범위를 지정하는데 사용 |
| @Repeatable* | Annotation을 반복해서 적용할 수 있게 함 |
* 표시 부분은 메타 Annotation으로 Annotation을 만드는데 사용되는 Annotation임
- @Override : 부모의 멤버를 오버라이딩할 경우 오탈자를 입력하는 실수를 하는 경우가 많은데 이를 방지하기 위한 Annotation. 오탈자로 인해서 부모의 Method가 아닌 새로운 Method가 생성되는 경우가 있는데 이럴 경우 오버라이딩 시 Method 선언부 앞에 @Override를 붙여주면 컴파일 에러를 발생시켜 이를 방지할 수 있다.
- @Deprecated : 앞으로 사용하지 않을 것을 권장하는 Field나 Method 앞에 붙인다. 컴파일 시 에러가 아니라 알림 메시지가 출력된다. 굳이 Method를 없애지 않고 Deprecated Annotation을 사용하여 알리는 이유는 해당 Annotation을 사용하기 이전에 작성된 코드에서는 Method를 없앰으로써 프로그램이 정상적으로 동작하지 않는 경우가 발생할 것이기 때문에 호환성을 위해 Method를 없애지 않고 알려주는 것이다.
- @FunctionalInterface : 함수형 인터페이스의 제약사항이 지켜지고 있는지 확인하는 Annotation. 컴파일러(javac.exe)가 사용하는 Annotation이며 함수형 인터페이스에는 하나의 추상 Method만 있어야 한다는 제약이 있는데 이를 컴파일러가 검사하는 역할을 수행하며 제약이 지켜지지 않았을 시 컴파일 에러가 발생한다.
- @SuppressWarning : 컴파일러의 경고 메시지를 나타나지 않도록 기능하는 Annotation. 컴파일러(javac.exe)가 사용하는 Annotation이며 Annotation 뒤 ( ) 내에 출력을 원하지 않는 경고를 문자열로 지정해주면 컴파일러가 출력되지 않도록 하며 프로그램에게 해당 경고를 확인했다고 알린다.
메타 Annotation
메타 Annotation은 Annotation을 만들 때 사용하는 Annotation으로 java.lang.annotation 패키지에 포함되어 있다.
| Annotation | 역할 |
| @Target | Annotation을 적용할 수 있는 대상을 지정하는데 사용 |
| @Documented | Annotation 정보가 javadoc으로 작성된 문서에 포함되도록 함 |
| @Inherited | Annotation이 자손 클래스에 상속되도록 함 |
| @Retention | Annotation이 유지되는 범위를 지정하는데 사용 |
| @Repeatable | Annotation을 반복해서 적용할 수 있도록 하는데 사용 |
- @Target : Annotation을 정의할 때 적용 대상을 지정하는데 사용한다. 즉, 해당 Annotation을 어디에 붙일 수 있는가를 지정한다. 타입(클래스, 인터페이스, enum), 필드, 메서드, 생성자, 인스턴스 변수에 사용할 수 있는 Annotation이다.
- @Retention : Annotation이 유지되는 기간을 지정하는데 사용된다. 컴파일러에 의해 사용되는 Annotation의 유지 정책은 Source이며 오버라이딩이 제대로 되었는지 확인하는 용도이기 때문에 컴파일 시에만 확인하고 사라진다. 실행 시에 Annotation 정책은 Runtime이며 컴파일 시간을 포함해서 런타임까지 존재한다.
- @Documented : javadoc으로 작성된 문서에 포함시키기 위해서 @Documented Annotation을 사용한다. javadoc을 통해 자동으로 HTML 문서가 생성되게 되고 이 문서에 내용이 포함되게 된다.
- @Inherited : Annotation을 자손 클래스에 상속하고자 할 때 사용한다.
- @Repeatable : 반복해서 사용할 수 있는 Annotation을 정의할 때 사용한다. @Repeatable인 @ToDo를 하나로 묶을 컨테이너 Annotation도 정의해야 한다.
Annotation 타입 정의 방법
Annotation을 직접 만들어서 사용할 수 있으며 @Interface를 사용해서 정의한다. Annotation의 Method는 추상 메서드이며 Annotation을 적용할 때 지정한다. 이 때 순서는 없다.
사용자 Annotation의 특징
- Default 값을 지정할 수 있다. 적용 시에 값을 지정하지 않으면 Null을 제외한 사용될 수 있는 기본값을 지정한다.
- 요소가 하나이고 이름이 value일 때는 요소의 이름을 생략할 수 있다.
- 요소의 타입이 배열 일 때 요소가 여러개라면 { } 를 사용해야 한다.
- 모든 Annotation의 조상은 Annotation이라는 인터페이스이다. 그러므로 모든 Annotation은 Annotation 인터페이스의 추상 메서드를 상속받게 된다. 이 때 해당 추상 메서드들은 따로 구현하지 않아도 컴파일러가 자동으로 구현해주기 때문에 사용할 수 있다.
- Marker Annotation은 요소가 하나도 정의되지 않은 Annotation을 말한다.
Annotation 요소의 규칙
Annotation의 요소를 선언할 때는
- 요소의 타입은 기본형, String, enum, annotation, Class만 허용된다.
- 추상 메서드의 ( ) 안에 매개변수를 선언할 수 없다.
- 예외를 선언할 수 없다.
- 요소를 타입 매개변수로 정의할 수 없다.
는 규칙을 반드시 지켜야 한다.
'Java' 카테고리의 다른 글
| 문자열 비교 - Equals() 와 == 연산자의 차이 (0) | 2024.01.09 |
|---|---|
| extends와 implements (0) | 2023.08.24 |
| Spring과 Spring Boot (0) | 2023.08.07 |