Java에서 @ 기호로 시작하는 것을 "애너테이션(Annotation)"이라고 부릅니다. 애너테이션은 코드의 메타데이터를 제공하며, 컴파일러에게 정보를 제공하거나, 런타임(runtime) 동작을 변경하거나, 소프트웨어 도구에서 사용할 수 있는 정보를 제공하는 등의 용도로 사용됩니다.
애너테이션은 크게 세 가지 범주로 나눌 수 있습니다:
마커 애너테이션(Marker Annotation): 이러한 애너테이션은 메소드, 클래스, 혹은 다른 애너테이션에 특정 특성을 부여하기 위해 사용됩니다. 예를 들어, @Override 애너테이션은 해당 메소드가 부모 클래스의 메소드를 오버라이드한다는 것을 명시합니다. 마커 애너테이션은 메타데이터를 추가하는 가장 간단한 형태로, 어떤 값을 받지 않고 이름만으로 특정 특성을 부여합니다.@Override
public String toString() {
return "This is an example.";
}
이 애너테이션은 컴파일러에게 이 메서드가 부모 클래스의 메서드를 오버라이드하고 있는지 확인하도록 요청하는 것입니다. 만약 실제로 오버라이드하고 있는 메서드가 없다면 컴파일러는 오류를 발생시킵니다.
싱글 값 애너테이션(Single-Value Annotation): 이러한 애너테이션은 하나의 값만을 받을 수 있습니다. 예를 들어, @SuppressWarnings 애너테이션은 컴파일러가 경고 메시지를 출력하지 않도록 요청하는 데 사용되며, 이 애너테이션은 무시할 경고의 유형을 문자열 값으로 받습니다.@SuppressWarnings("unchecked")
public void exampleMethod() {
// Some code that causes unchecked warning
}
이 경우, "unchecked"라는 경고를 무시하도록 컴파일러에 지시하고 있습니다.
풀 값 애너테이션(Full-Value Annotation): 이러한 애너테이션은 여러 값을 받을 수 있습니다. 예를 들어, 스프링 프레임워크에서 @RequestMapping 애너테이션은 HTTP 요청을 특정 메서드에 매핑하는 데 사용됩니다. 이 애너테이션은 method와 path라는 두 가지 값을 받을 수 있습니다.@RequestMapping(method = RequestMethod.GET, path = "/example")
public String exampleMethod() {
// Code to handle GET request at "/example"
return "example";
}
이 경우, method와 path라는 두 가지 속성을 이용해 HTTP GET 요청을 "/example" 경로에 있는 exampleMethod 메서드에 매핑하도록 스프링 프레임워크에 지시하고 있습니다.
Java에서는 @ 기호 뒤에 애너테이션의 이름을 작성하여 애너테이션을 코드에 추가합니다. 그 뒤에 소괄호 ()를 추가하고 그 안에 필요한 값을 지정할 수 있습니다.
애너테이션은 컴파일 타임과 런타임 중 언제 해석되는지에 따라 다음과 같이 분류할 수 있습니다:
소스(Source) 애너테이션:이 애너테이션은 소스 코드에서만 유지되며, 컴파일 시점에 컴파일러에 의해 처리되고 제거됩니다. 즉, 컴파일 후의 클래스 파일(.class)에는 포함되지 않습니다. 주로 컴파일러에게 어떤 정보를 전달하거나 컴파일러의 동작을 제어하는 데 사용됩니다. 예를 들어, @Override와 @SuppressWarnings 애너테이션은 소스 애너테이션에 해당합니다.
클래스(Class) 애너테이션: 클래스 애너테이션은 컴파일러에 의해 처리되며, 컴파일 후의 클래스 파일에도 포함됩니다. 그러나 런타임 시점에는 JVM(Java Virtual Machine)에 의해 로드되지 않습니다. 즉, 런타임 시에는 해당 애너테이션의 정보를 읽을 수 없습니다. 이 유형의 애너테이션은 매우 드뭅니다.
자바에 내장된 애너테이션 외에도, 많은 프레임워크와 라이브러리들이 자체적인 애너테이션을 제공합니다. 예를 들어, 스프링 프레임워크는 @Autowired, @Component, @Service 등의 애너테이션을 제공합니다.
메타데이터 (Metadata)
메타데이터는 데이터에 대한 데이터라고 할 수 있습니다. 메타데이터는 데이터의 구조, 특성, 위치, 생성과 수정에 대한 정보 등을 설명하며, 데이터를 이해하고 효율적으로 사용하는 데 도움을 줍니다. 예를 들어, 디지털 사진의 메타데이터는 촬영 일시, 카메라 모델, 노출 시간 등의 정보를 포함할 수 있습니다. 프로그래밍에서 메타데이터는 변수의 타입, 클래스와 메소드의 정의 등을 나타낼 수 있습니다. Java에서의 애너테이션은 일종의 메타데이터로, 코드의 동작을 제어하거나 개발 도구와 프레임워크에 정보를 제공하는 데 사용됩니다.
컴파일러 (Compiler)
컴파일러는 프로그래밍 언어로 작성된 소스 코드를 컴퓨터가 이해할 수 있는 기계어로 변환하는 프로그램입니다. 이 변환 과정을 컴파일이라고 합니다. 컴파일러는 변환하는 과정에서 코드의 문법을 검사하고, 필요한 최적화를 수행하며, 오류와 경고를 알려줍니다. Java에서는 javac라는 컴파일러를 사용하여 .java 소스 파일을 .class 바이트코드 파일로 컴파일합니다.
런타임 (Runtime)
런타임은 프로그램이 실행되는 동안의 시간을 가리키는 용어입니다. 런타임에서는 프로그램의 동작이 결정되며, 사용자 입력을 처리하고 결과를 출력하는 등의 동작이 수행됩니다. 런타임 동작은 소스 코드나 컴파일러의 제어를 벗어난 상태에서 발생하며, 프로그램의 동적 행동을 포함합니다. 예를 들어, Java에서 NullPointerException이 발생하는 것은 런타임 동작의 일부입니다.
Java에서의 "런타임 애너테이션"은 애너테이션 정보가 런타임에도 유지되는 것을 의미합니다. 즉, 런타임에서 이 애너테이션 정보를 통해 프로그램의 동작을 제어할 수 있습니다. 이를 가능하게 하는 Java의 기능 중 하나가 리플렉션 (Reflection)입니다.