> For the complete documentation index, see [llms.txt](https://docs.sysout.co.kr/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sysout.co.kr/base-language/java/java-advanced/annotation-type.md).

# Annotation Type

## Annotation Type

이 문서에서는 <mark style="color:blue;">Java Annotation Type</mark>을 만들고 사용하는 방법에 대해서 살펴본다. 이 내용은 오라클 튜토리얼 문서를 참고하였으며, 하단에 링크를 첨부한다.

{% embed url="<https://docs.oracle.com/javase/tutorial/java/annotations/declaring.html>" %}

### Annotation Type 생성

Annotation Type은 다음의 형태를 가진다.

```java
public @interface 이름 {

}
```

직접 해당 코드를 작성하거나 생성 메뉴에서 <mark style="color:blue;">Annotation</mark>을 선택하여 생성할 수 있다.

<div align="left"><img src="https://4208234536-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M_TNZwLuHV9ipYLbvRq%2Fuploads%2FSj5zu0WVEE05FdcM3Krq%2Fimage.png?alt=media&amp;token=4d2ca77e-6b54-4b29-ac77-080730b3a409" alt=""></div>

### 예제 - 사용할 Annotation 클래스

이 문서에서 사용할 예시 <mark style="color:blue;">Annotation</mark> 코드는 다음과 같다.

{% code title="TestEntity.java" %}

```java
package com.hacademy.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestEntity {
	String author() default "";
	String date() default "N/A";
	String comment() default "";
}
```

{% endcode %}

생성한 Annotation Type에 다음 두 가지 <mark style="color:blue;">Annotation</mark>을 설정하여 적용 방식을 지정한다.

* Retention - 생성한 Annotation이 어느 시점까지 지속되어야 하는지에 대해서 설정할 수 있다
* Target - 생성한 Annotation을 적용할 수 있는 대상을 배열 형태로 지정한다.

TestEntity에 대한 설정은 다음과 같다.

```java
//class, interface, enum에 설정 가능하다
@Target(ElementType.TYPE)

//런타임 시점까지 유지되어 Reflection 등의 코드에서 불러올 수 있다
@Retention(RetentionPolicy.RUNTIME)
```

또한 Annotation Type은 옵션으로 지정할 수 있는 데이터들을 내부에 선언할 수 있다. 기본값을 부여하지 않을 경우 반드시 설정해야 하며, default 키워드로 기본값을 부여하면 선택적으로 설정하고 미설정 시 기본값이 적용된다.

TestEntity는 3개의 옵션을 지정할 수 있다.

* author : 작성자 정보 (선택)
* date : 작성일 정보 (선택)
* comment : 작성자 코멘트 (선택)

```java
String author() default "";
String date() default "N/A";
String comment() default "";
```

### 예제 - 생성한 Annotation type의 적용

이전 예제에서 생성한 `TestEntity`를 적용한 클래스 코드는 다음과 같다.

```java
package com.hacademy.annotation;

@TestEntity(author = "hacademy", date = "2022-03-03", comment = "테스트를 위한 Annotation")
public class Item {
	private String name;
	private int price;
	
	public void setName(String name) {
		this.name = name;
	}
	public void setPrice(int price) {
		this.price = price;
	}
	public String getName() {
		return name;
	}
	public int getPrice() {
		return price;
	}
	
	@Override
	public String toString() {
		return "Item [name=" + name + ", price=" + price + "]";
	}
}
```

적용은 `@TestEntity`의 형태로 하며, 옵션의 경우 default값을 설정해두었으므로 필요시 생략 가능하다.

{% hint style="info" %}
Annotation 내부의 데이터 중 변수명이 <mark style="color:red;">value</mark>인 항목은 하나만 작성할 경우 옵션명을 작성하지 않아도 된다.

다음 두 코드는 같은 코드이다.

```java
@Test(value="hello")
```

```java
@Test("hello")
```

{% endhint %}
