학습
Java 애너테이션과 리플렉션
Java 애너테이션과 리플렉션 — 중급
애너테이션과 리플렉션
1. 도입 (왜 배워야 하는가)
애너테이션(Annotation)과 리플렉션(Reflection)은 Java에서 강력한 기능을 제공하여 코드의 유연성을 높이고, 메타 프로그래밍을 가능하게 합니다. 실무에서는 이 두 가지를 활용하여 코드의 유지보수성을 높이고, 반복적인 작업을 줄이며, 프레임워크를 구축하는 데 도움을 줍니다.
예를 들어, Spring 프레임워크에서는 애너테이션을 통해 의존성 주입(Dependency Injection)을 간편하게 처리합니다. 만약 애너테이션과 리플렉션을 이해하지 못한다면, 복잡한 프레임워크를 제대로 활용하지 못하거나, 비효율적인 코드 작성으로 이어질 수 있습니다.
2. 핵심 개념 설명
애너테이션
애너테이션은 코드에 메타데이터를 추가하는 방법으로, 주석과 유사하지만 컴파일러나 JVM에서 처리할 수 있는 정보를 제공합니다. 예를 들어, @Override는 메서드가 부모 클래스의 메서드를 오버라이드함을 나타냅니다.
비유: 애너테이션은 도서관의 책에 붙은 태그와 같습니다. 태그는 책의 주제나 내용을 간단히 알려주며, 책을 찾는 데 도움을 줍니다.
리플렉션
리플렉션은 Java에서 클래스를 동적으로 탐색하고, 객체의 메타정보를 얻거나, 메서드를 호출할 수 있는 기능입니다. 이를 통해 런타임 시점에서 객체의 타입과 메서드 정보를 알 수 있습니다.
비유: 리플렉션은 상자 안에 무엇이 들어 있는지 보거나, 상자에 담긴 물건을 꺼내는 것과 같습니다. 상자를 열고 그 안에 무엇이 있는지 확인할 수 있습니다.
| 용어 | 설명 |
|---|---|
| 애너테이션 | 메타데이터를 제공하는 특별한 형태의 주석 |
| 리플렉션 | 런타임 시점에서 객체의 정보를 탐색하고 조작하는 방법 |
3. 기본 코드 예제
// 애너테이션 정의
@interface MyAnnotation {
String value();
}
// 애너테이션 사용
@MyAnnotation("Hello, Annotation!")
public class MyClass {
public void myMethod() {
System.out.println("My Method");
}
}
// 리플렉션을 이용한 애너테이션 접근
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) throws Exception {
Class<?> clazz = MyClass.class; // MyClass 클래스 정보 얻기
MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class); // 애너테이션 가져오기
System.out.println(annotation.value()); // 애너테이션의 값 출력
Method method = clazz.getMethod("myMethod"); // 메서드 정보 얻기
method.invoke(clazz.getDeclaredConstructor().newInstance()); // 메서드 호출
}
}
실행 결과
Hello, Annotation!
My Method
코드 한 줄씩 동작 설명
@interface MyAnnotation- 애너테이션을 정의합니다.@MyAnnotation("Hello, Annotation!")-MyClass에 애너테이션을 적용합니다.Class<?> clazz = MyClass.class;-MyClass의 클래스를 가져옵니다.MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class);- 애너테이션 정보를 얻습니다.System.out.println(annotation.value());- 애너테이션의 값을 출력합니다.Method method = clazz.getMethod("myMethod");-myMethod메서드 정보를 가져옵니다.method.invoke(clazz.getDeclaredConstructor().newInstance());-myMethod를 호출합니다.- 올바른 코드: 기본값을 제공해야 합니다.
- 올바른 코드: 예외 처리를 추가해야 합니다.
- 애너테이션은 메타데이터를 제공하여 코드의 가독성과 유지보수성을 높입니다.
- 리플렉션은 런타임 시점에서 클래스의 정보를 동적으로 탐색하고 조작할 수 있게 합니다.
- 이 두 기능은 Java 프레임워크에서 광범위하게 사용됩니다.
- 다음에 학습하면 좋은 주제로는 Spring 프레임워크의 의존성 주입, JPA에서의 애너테이션 활용이 있습니다.
4. 실전 활용 예제
1. 유효성 검사
쇼핑몰에서 장바구니를 구현할 때, 상품의 가격이 유효한지 검사하는 애너테이션을 만들 수 있습니다.
@interface Price {
double min() default 0;
}
class Product {
@Price(min = 0)
private double price;
public Product(double price) {
this.price = price;
}
}
2. 의존성 주입
Spring 프레임워크에서 @Autowired 애너테이션을 사용해 의존성을 자동으로 주입합니다.
class Service {
// 의존성이 자동 주입됨
}
class Controller {
@Autowired
private Service service; // Service 객체가 자동으로 주입됨
}
5. 흔한 실수와 주의사항
실수 1: 애너테이션을 잘못 정의하기
// 잘못된 애너테이션 정의
@interface MyAnnotation {
String value(); // 기본값이 없음
}
@interface MyAnnotation {
String value() default "default value";
}
실수 2: 리플렉션 사용 시 예외 처리 누락
// 예외 처리를 하지 않음
Method method = clazz.getMethod("myMethod");
method.invoke(clazz.newInstance()); // 예외 발생 가능
try {
Method method = clazz.getMethod("myMethod");
method.invoke(clazz.getDeclaredConstructor().newInstance());
} catch (Exception e) {
e.printStackTrace();
}