자바 애너테이션
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
자바 애너테이션은 자바 언어에서 메타데이터를 표현하는 기능으로, 컴파일러나 런타임에 코드에 대한 정보를 제공한다. 2002년 JSR-175를 통해 도입되어 JDK 1.5부터 정식으로 지원되었으며, 내장 애너테이션과 사용자 정의 애너테이션을 모두 사용할 수 있다. 내장 애너테이션으로는 `@Override`, `@Deprecated`, `@SuppressWarnings` 등이 있으며, 메타 애너테이션으로는 `@Retention`, `@Target`, `@Documented`, `@Inherited` 등이 있다. 자바 7 이후에는 `@SafeVarargs`, `@FunctionalInterface`, `@Repeatable`이 추가되었다. 애너테이션은 컴파일 시점에 오류를 확인하거나, 런타임에 리플렉션을 통해 정보를 활용하는 등 다양한 방식으로 활용된다. 자바 외에도 Visual C++의 SAL 주석과 같이 다른 언어에서도 유사한 기능을 제공한다.
더 읽어볼만한 페이지
- 자바 (프로그래밍 언어) - 자바 애플릿
자바 애플릿은 웹 페이지에서 실행되는 자바 기반 프로그램으로, 웹 상호작용성을 높였으나 기술적 문제와 웹 표준 기술 발전에 따라 쇠퇴하여 사용이 중단되었다. - 자바 (프로그래밍 언어) - 자바FX
JavaFX는 자바 기반의 UI 구축 플랫폼으로, 다양한 플랫폼을 지원하며 풍부한 UI 기능들을 제공하고, Java 8부터 JDK에 포함되었다가 JDK 11부터 분리되어 관리된다. - 자바 사양 요청 - 자바 플랫폼, 마이크로 에디션
자바 ME는 임베디드 및 모바일 장치에서 자바 앱을 실행하는 플랫폼으로, 피처폰에서 주로 사용되었으며 다양한 프로파일과 에뮬레이터, 개발 도구를 제공하고 JSR을 통해 기능이 확장된다. - 자바 사양 요청 - 자바 커뮤니티 프로세스
자바 커뮤니티 프로세스는 자바 기술 명세의 개발 및 관리를 담당하는 조직으로, 자바 기술 표준화와 발전에 기여해왔으나 운영 방식에 대한 비판과 여러 논란에 직면해 있다.
| 자바 애너테이션 | |
|---|---|
| 자바 애너테이션 | |
![]() | |
| 일반 정보 | |
| 유형 | 메타데이터 |
| 설계자 | 길라드 브라차 |
| 개발자 | 썬 마이크로시스템즈 (현재 오라클 소유) |
| 최초 출시 | 2004년 (J2SE 5.0) |
| 자바 명칭 | 애너테이션 (annotation) |
| 특징 | |
| 주요 기능 | 컴파일러에게 코드 작성 방법 지시 컴파일 또는 배포 시 처리 런타임 시 처리 |
| 목적 | 컴파일러 지시 빌드 도구 지시 런타임 동작 변경 |
| 문법 | |
| 선언 위치 | 클래스, 메서드, 변수 등 |
| 형태 | @애너테이션이름 |
| 파라미터 | 요소-값 쌍 (선택 사항) |
| 활용 | |
| 예시 | @Override (메서드 재정의) @Deprecated (사용 중단된 요소) @SuppressWarnings (컴파일러 경고 억제) |
| 유지 정책 (Retention Policy) | |
| SOURCE | 컴파일러에 의해서만 사용, .class 파일에 포함되지 않음 |
| CLASS | 컴파일러에 의해 .class 파일에 저장되지만, 런타임에는 JVM에 의해 유지되지 않음 |
| RUNTIME | 런타임 시 JVM에 의해 유지, 리플렉션을 통해 접근 가능 |
| 대상 (Target) | |
| ANNOTATION_TYPE | 다른 애너테이션에 적용 |
| CONSTRUCTOR | 생성자에 적용 |
| FIELD | 필드 (인스턴스 변수)에 적용 |
| LOCAL_VARIABLE | 지역 변수에 적용 |
| METHOD | 메서드에 적용 |
| PACKAGE | 패키지에 적용 |
| PARAMETER | 메서드 파라미터에 적용 |
| TYPE | 클래스, 인터페이스 (annotation type 포함), enum에 적용 |
2. 역사
자바 플랫폼은 초기부터 다양한 임시 애너테이션 메커니즘을 가지고 있었다. 예를 들어,
자바는 언어에 내장된 여러 애너테이션을 정의한다. 표준 애너테이션 7개 중 3개는 java.lang 패키지에 속하며, 나머지 4개는 `java.lang.annotation` 패키지에서 가져온다.[9][10][5][6]transient 수정자나 @Deprecated 자바독 태그 등이 사용되었다. 자바 규격 요청 JSR-175는 2002년 자바 커뮤니티 프로세스에 범용 애너테이션(메타데이터라고도 함) 기능을 도입할 것을 제안했으며, 이는 2004년 9월에 최종 승인되었다.[4]
애너테이션은 자바 개발 키트 (JDK) 버전 1.5부터 자바 언어 자체에서 사용할 수 있게 되었다. JDK 1.5에는 컴파일 시 애너테이션 처리를 위한 임시 인터페이스를 제공하는 apt 도구가 포함되었다. 이후 JSR-269가 이러한 처리 방식을 공식화하였고, 이 기능은 JDK 버전 1.6부터 자바C 컴파일러에 통합되었다.
3. 내장 애너테이션
자바 코드에 직접 적용되는 내장 애너테이션에는 `@Override`, `@Deprecated`, `@SuppressWarnings` 등이 있다. 다른 애너테이션에 적용되는 애너테이션, 즉 메타 애너테이션으로는 `@Retention`, `@Documented`, `@Target`, `@Inherited`가 있다.
자바 7부터는 `@SafeVarargs`, `@FunctionalInterface`(자바 8), `@Repeatable`(자바 8)과 같은 애너테이션들이 추가로 도입되었다.
3. 1. 자바 코드에 적용되는 내장 애너테이션
자바는 언어에 내장된 여러 애너테이션을 제공한다. 표준 애너테이션 7개 중 3개는 java.lang 패키지에 속하고, 나머지 4개는 `java.lang.annotation` 패키지에서 가져온다.[9][10][5][6] 자바 코드에 직접 적용되는 내장 애너테이션은 다음과 같다.
public class Animal {
public void speak() {
}
public String getType() {
return "Generic animal";
}
}
public class Cat extends Animal {
@Override
public void speak() { // 올바른 재정의
System.out.println("Meow.");
}
@Override
public String gettype() { // 오타로 인한 컴파일 오류 발생: getType() 이어야 함
return "Cat";
}
}3. 2. 메타 애너테이션 (다른 애너테이션에 적용되는 애너테이션)
다른 애너테이션에 적용되는 애너테이션으로, '메타 애너테이션'이라고도 부른다.
| 애너테이션 | 설명 |
|---|---|
@Retention | 표시된 애너테이션이 코드에만 저장되는지, 클래스로 컴파일되는지, 또는 리플렉션을 통해 런타임에 사용할 수 있는지 지정한다. |
@Documented | 다른 애너테이션을 문서에 포함하도록 표시한다. |
@Target | 다른 애너테이션을 표시하여 애너테이션을 적용할 수 있는 자바 요소의 종류를 제한한다. |
@Inherited | 다른 애너테이션을 주석 처리된 클래스의 하위 클래스에 상속되도록 표시한다 (기본적으로 애너테이션은 하위 클래스에 의해 상속되지 않는다). |
3. 3. 자바 7 이후 추가된 애너테이션
자바 7부터 다음 세 가지 애너테이션이 추가되었다.@SafeVarargs: 자바 7부터 추가된 애너테이션이다. 제네릭스 가변 인자(varargs) 매개변수를 사용하는 메서드나 생성자를 호출할 때 발생할 수 있는 경고를 억제한다.@FunctionalInterface: 자바 8부터 추가되었다. 해당 타입 선언이 함수형 인터페이스임을 명시적으로 지정한다.@Repeatable: 자바 8부터 추가되었다. 동일한 선언에 특정 애너테이션을 여러 번 반복해서 적용할 수 있도록 허용한다.
4. 예제
자바의 '''애너테이션'''은 클래스, 인터페이스, 메서드, 필드, 패키지 등에 메타데이터로서 부가 정보를 기입하는 기능이다.[1] Java SE 5부터 도입되었으며, 개발자는 `java.lang.annotation.Annotation` 인터페이스를 구현하여 직접 애너테이션을 만들 수도 있다.[1]
애너테이션은 자바에서 기본적으로 제공하는 내장 애너테이션과 사용자가 특정 목적을 위해 직접 정의하는 사용자 정의 애너테이션으로 나눌 수 있다. 아래 하위 섹션에서는 각각의 구체적인 사용 예제를 살펴본다.
4. 1. 내장 애너테이션 사용 예제
다음은 `@Override` 애너테이션의 사용 예시이다.public class Animal {
public void speak() {
}
public String getType() {
return "Generic animal";
}
}
public class Cat extends Animal {
@Override
public void speak() { // 올바른 재정의이다.
System.out.println("Meow.");
}
@Override
public String gettype() { // 오타로 인한 컴파일 시점 오류: getType()이어야 한다.
return "Cat";
}
}
`@Override` 애너테이션은 해당 메서드가 부모 클래스의 메서드를 재정의(override)한다는 것을 명시적으로 나타낸다. 컴파일러는 이 애너테이션을 보고 해당 메서드가 상위 클래스의 메서드와 일치하는지 확인한다.
위 예시에서 `Cat` 클래스의 `gettype()` 메서드는 `@Override` 애너테이션이 붙어 있지만, 실제로는 부모 클래스인 `Animal`의 `getType()` 메서드를 재정의하지 못한다. 이는 메서드 이름의 대소문자가 일치하지 않기 때문이다 (`getType` vs `gettype`). `@Override` 애너테이션 덕분에 이러한 실수가 컴파일 시점에 오류로 발견된다.
만약 `@Override` 애너테이션이 없었다면, 컴파일러는 `gettype()`을 `Cat` 클래스에 새로 정의된 메서드로 간주했을 것이고, 개발자는 의도한 대로 메서드 재정의가 이루어지지 않았다는 사실을 알아차리기 어려웠을 것이다.
4. 2. 사용자 정의 애너테이션
애너테이션 타입을 선언하는 것은 일반적인 인터페이스 선언과 비슷하지만, 예약어 `interface` 앞에 앳사인 기호(`@`)를 붙인다.// @Twizzle은 메서드 toggle()에 대한 애너테이션이다.
@Twizzle
public void toggle() {
// 메서드 내용
}
// Twizzle 애너테이션을 선언한다.
public @interface Twizzle {
// 애너테이션 요소 정의 (선택 사항)
}
애너테이션은 키-값 쌍 형태의 요소를 가질 수 있으며, 각 요소는 애너테이션 타입의 메서드로 정의된다. 이 메서드 선언은 매개변수나 `throws` 절을 가질 수 없다. 반환 타입은 원시 자료형, String, Class, 열거형, 다른 애너테이션 타입, 그리고 앞서 언급된 타입들의 배열로 제한된다. 메서드는 기본값을 가질 수 있다.
// @Edible(value = true)와 동일하다. value 요소의 이름이 'value'일 경우 생략 가능하다.
@Edible(true)
Item item = new Carrot();
public @interface Edible {
boolean value() default false; // 기본값은 false
}
// 여러 요소를 가질 수 있다.
@Author(first = "Oompah", last = "Loompah")
Book book = new Book();
public @interface Author {
String first();
String last();
}
애너테이션 자체에도 다른 애너테이션(메타 애너테이션)을 붙여서 해당 애너테이션이 어디에, 언제까지 사용될 수 있는지를 명시할 수 있다.
// 이 애너테이션 정보가 런타임에도 유지되어 리플렉션을 통해 접근 가능하게 한다.
@Retention(RetentionPolicy.RUNTIME)
// 이 애너테이션은 클래스의 메서드에만 적용될 수 있다.
@Target({ElementType.METHOD})
public @interface Tweezable {
// 애너테이션 요소 정의
}
컴파일러는 문법적인 목적으로 몇 가지 특별한 애너테이션(`@Deprecated`, `@Override`, `@SuppressWarnings` 등)을 예약해두고 사용한다.
애너테이션은 소프트웨어 프레임워크에서 자주 사용된다. 외부 설정 파일(XML 등)이나 프로그래밍 방식(API 호출)으로 설정해야 하는 클래스나 메서드의 동작을 애너테이션을 통해 편리하게 지정할 수 있다. 예를 들어, 다음은 JPA에서 사용되는 애너테이션이 적용된 데이터 클래스이다.
// 이 클래스를 엔티티 빈으로 선언한다.
@Entity
// 이 빈을 SQL 테이블 "people"에 매핑한다.
@Table(name = "people")
public class Person implements Serializable {
// 이 필드를 기본 키 열에 매핑한다.
@Id
// 데이터베이스가 자동으로 새 기본 키 값을 생성하도록 한다.
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
// 열의 길이를 32자로 제한한다.
@Column(length = 32)
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
애너테이션 자체는 메서드 호출처럼 직접적인 동작을 수행하지 않는다. 대신, 애너테이션이 붙은 클래스 객체가 런타임에 JPA 같은 프레임워크 구현체에 전달되면, 해당 구현체가 애너테이션 정보를 읽어 객체 관계형 매핑과 같은 필요한 작업을 수행한다.
아래는 사용자 정의 애너테이션을 정의하고 사용하는 전체 예제이다.
package com.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- 작업이 완료되지 않았음을 나타내는 애너테이션.
- 문서에도 포함되고(@Documented), 런타임까지 유지되며(@Retention),
- 여러 종류의 대상(@Target)에 적용 가능하고, 하위 클래스에도 상속된다(@Inherited).
- /
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD,
ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE,
ElementType.PACKAGE, ElementType.FIELD, ElementType.LOCAL_VARIABLE})
@Inherited
public @interface Unfinished {
// 작업의 우선순위를 나타내는 열거형
public enum Priority { LOW, MEDIUM, HIGH }
// 작업 내용을 설명하는 문자열 (필수 요소)
String value();
// 작업을 변경한 사람들의 목록 (기본값: 빈 배열)
String[] changedBy() default "";
// 마지막으로 변경한 사람들의 목록 (기본값: 빈 배열)
String[] lastChangedBy() default "";
// 작업 우선순위 (기본값: MEDIUM)
Priority priority() default Priority.MEDIUM;
// 작업을 생성한 사람 (기본값: "James Gosling")
String createdBy() default "James Gosling";
// 마지막 변경 날짜 (기본값: "2011-07-08")
String lastChanged() default "2011-07-08";
}
package com.annotation;
/**
- 현재 개발 중임을 나타내는 애너테이션.
- /
public @interface UnderConstruction {
// 담당자 (기본값: "Patrick Naughton")
String owner() default "Patrick Naughton";
// 상태 설명 (기본값: "Object is Under Construction.")
String value() default "Object is Under Construction.";
// 생성자 (기본값: "Mike Sheridan")
String createdBy() default "Mike Sheridan";
// 마지막 변경 날짜 (기본값: "2011-07-08")
String lastChanged() default "2011-07-08";
}
package com.validators;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import com.annotation.UnderConstruction;
import com.annotation.Unfinished;
import com.annotation.Unfinished.Priority;
import com.util.Util; // 가상의 유틸리티 클래스
/**
- 날짜 유효성을 검사하는 클래스.
- 이 클래스 자체가 아직 개발 중임을 나타낸다 (@UnderConstruction).
- /
@UnderConstruction(owner="Jon Doe")
public class DateValidator implements Validator {
/**
- 날짜 문자열의 유효성을 검사한다.
- @param context Faces 컨텍스트
- @param component UI 컴포넌트
- @param value 검사할 값 (날짜 문자열)
- @throws ValidatorException 유효성 검사 실패 시
- /
public void validate(FacesContext context, UIComponent component, Object value)
throws ValidatorException {
String date = (String) value;
String errorLabel = "Please enter a valid date."; // 기본 오류 메시지
// 컴포넌트 속성에서 오류 메시지를 가져올 수 있다면 사용한다.
if (!component.getAttributes().isEmpty()) {
errorLabel = (String) component.getAttributes().get("errordisplayval");
}
// Util 클래스를 사용하여 날짜 유효성을 검사한다.
if (!Util.validateAGivenDate(date)) { // 유효하지 않은 경우
// 이 부분의 로직이 아직 미완성임을 나타낸다 (@Unfinished).
// 메시지를 컨텍스트에 추가할지 여부를 확인해야 한다.
@Unfinished(changedBy = "Steve",
value = "whether to add message to context or not, confirm",
priority = Priority.HIGH
)
FacesMessage message = new FacesMessage();
message.setSeverity(FacesMessage.SEVERITY_ERROR);
message.setSummary(errorLabel);
message.setDetail(errorLabel);
// 유효성 검사 예외를 발생시킨다.
throw new ValidatorException(message);
}
}
}
5. 애너테이션 처리
자바 소스 코드가 컴파일될 때, 애너테이션은 애너테이션 프로세서라고 하는 컴파일러 플러그인에 의해 처리될 수 있다. 프로세서는 정보 메시지를 생성하거나 추가적인 자바 소스 파일 또는 리소스를 생성할 수 있으며, 이는 다시 컴파일되고 처리될 수 있다. 그러나 애너테이션 프로세서는 애너테이션이 적용된 코드 자체를 수정할 수 없다.[4] JDK 버전 1.5에서는 apt 도구가 컴파일 시 애너테이션 처리를 위한 임시 인터페이스를 제공했고, JSR-269가 이를 공식화하여 버전 1.6에서 자바C 컴파일러에 통합되었다.
자바 컴파일러는 애너테이션의 RetentionPolicy가 CLASS 또는 RUNTIME인 경우 클래스 파일에 애너테이션 메타데이터를 조건부로 저장한다. 나중에, JVM 또는 다른 프로그램은 메타데이터를 찾아 프로그램 요소와 상호 작용하거나 동작을 변경하는 방법을 결정할 수 있다.
애너테이션 프로세서를 사용하여 애너테이션을 처리하는 것 외에도, 자바 프로그래머는 리플렉션을 사용하여 애너테이션을 처리하는 자체 코드를 작성할 수 있다. Java SE 5는 java.lang.reflect 패키지에 정의된 새로운 인터페이스를 지원한다. 이 패키지에는 Class, Constructor, Field, Method 및 Package를 포함하는 자바 리플렉션 클래스에 의해 구현되는 AnnotatedElement라는 인터페이스가 포함되어 있다. 이 인터페이스의 구현은 현재 자바 가상 머신에서 실행 중인 프로그램의 애너테이션이 적용된 요소를 나타내는 데 사용된다. 이 인터페이스를 통해 애너테이션을 리플렉션 방식으로 읽을 수 있다.AnnotatedElement 인터페이스는 RUNTIME 보존을 가진 애너테이션에 대한 접근을 제공한다. 이 접근은 getAnnotation, getAnnotations, 및 isAnnotationPresent 메서드에 의해 제공된다. 애너테이션 타입은 클래스와 마찬가지로 바이트 코드 파일로 컴파일되어 저장되므로, 이러한 메서드에서 반환된 애너테이션은 일반 자바 객체처럼 쿼리할 수 있다.
6. 다른 언어에서의 애너테이션
(내용 없음)
6. 1. Visual C++의 SAL 주석
마이크로소프트 비주얼 C++는 SAL 주석(SAL annotation)이라고 불리는 고유한 소스 코드 주석 언어를 지원한다.[7] SAL 주석은 함수의 인수나 반환값, 구조체나 클래스의 멤버 변수(필드)와 같은 C 언어/C++ 구문 요소를 수식하고, 동작이나 사양을 규정함으로써, 이것들을 이용하는 코드상의 오류를 컴파일러에 의해 지적할 수 있게 된다. 또한, SAL 주석에 의해 사양이 명확해지고, 공개된 헤더 파일 자체가 API 문서로 이용할 수 있게 된다. 비주얼 C++가 지원하는 코드 분석 기능(/analyze)은 SAL 주석에 대응하며[8], 일반적인 컴파일러 경고보다 상세한 힌트나 어드바이스를 출력할 수 있다.참조
[1]
웹사이트
Annotations
https://web.archive.[...]
Sun Microsystems
2011-09-30
[2]
서적
Java(TM) Language Specification
http://java.sun.com/[...]
Prentice Hall
[3]
웹사이트
A COMPARISON OF MICROSOFT'S C# PROGRAMMING LANGUAGE TO SUN MICROSYSTEMS' JAVA PROGRAMMING LANGUAGE: Metadata Annotations
https://web.archive.[...]
Dare Obasanjo
2012-09-20
[4]
웹사이트
JSR 175: A Metadata Facility for the JavaTM Programming Language
http://www.jcp.org/e[...]
Java Community Process
2006-11-02
[5]
웹사이트
Predefined Annotation Types
https://docs.oracle.[...]
Oracle Corporation
2016-12-17
[6]
웹사이트
The Built-In Annotations : Standard Annotations
http://www.java2s.co[...]
2016-12-17
[7]
문서
Using SAL Annotations to Reduce C/C++ Code Defects - Visual Studio | Microsoft Docs
https://docs.microso[...]
[8]
문서
Code Analysis for C/C++ Overview - Visual Studio | Microsoft Docs
https://docs.microso[...]
[9]
웹인용
Predefined Annotation Types
https://docs.oracle.[...]
Oracle Corporation
2016-12-17
[10]
웹인용
The Built-In Annotations : Standard Annotations
http://www.java2s.co[...]
2016-12-17
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com
