IT Developer/Java

Java 기초 <15. Java의 리플렉션(Reflection)과 애노테이션(Annotation) 활용>

TEMA_ 2025. 3. 16. 09:38
반응형

자바 Java

15. Java의 리플렉션(Reflection)과 애노테이션(Annotation) 활용

 

안녕하세요! 태마입니다.

Java 기초 강좌입니다.

 

강좌의 경우 

1. 주제 간단 정리

2. 상세 주제 정리

으로 이루어져 있습니다.

 

자바 Java

포스팅 시작하겠습니다 :)

1. 주제 간단 정리

 

1. 리플렉션(Reflection) 개념

**리플렉션(Reflection)**은 Java 프로그램이 실행 중에 클래스, 메서드, 필드 등 객체의 정보를 동적으로 조회하고 수정할 수 있는 기능입니다.
✔ 리플렉션을 사용하면 컴파일 타임에 알 수 없는 클래스의 정보를 런타임에 동적으로 처리할 수 있습니다.
✔ 예를 들어, 어떤 클래스에 어떤 메서드가 있는지, 메서드의 파라미터 등을 실행 중에 확인하고 조작할 수 있습니다.

📌 리플렉션의 주요 용도
동적 클래스 로딩 : 클래스를 런타임에 동적으로 로딩하고 객체 생성
어노테이션 처리 : 어노테이션을 런타임에 동적으로 분석
프레임워크 : 스프링, 하이버네이트 등에서 리플렉션을 사용하여 객체를 관리


 

2. 리플렉션 API 사용법

리플렉션을 활용하려면 java.lang.reflect 패키지를 사용합니다.
Class : 클래스에 대한 정보를 제공
Field : 클래스의 필드(변수)에 대한 정보 제공
Method : 클래스의 메서드에 대한 정보 제공
Constructor : 클래스의 생성자에 대한 정보 제공

클래스 정보 조회 예제

public class ReflectionExample {
    public static void main(String[] args) {
        try {
            // 클래스 정보 가져오기
            Class<?> clazz = Class.forName("java.lang.String");

            // 클래스 이름 출력
            System.out.println("클래스 이름: " + clazz.getName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

📌 Class.forName()을 사용하여 클래스 이름을 동적으로 로드하고, 클래스의 정보를 조회할 수 있음.


 

3. 리플렉션을 활용한 필드 및 메서드 접근

리플렉션을 사용하여 객체의 필드메서드에 동적으로 접근할 수 있습니다.
✔ 리플렉션을 통해 비공개(private) 필드나 메서드에도 접근 가능하므로, 보안에 유의해야 합니다.

필드 접근 예제

import java.lang.reflect.Field;

public class FieldReflectionExample {
    private String name = "John";

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Field field = FieldReflectionExample.class.getDeclaredField("name");
        field.setAccessible(true);  // private 필드 접근 허용
        FieldReflectionExample obj = new FieldReflectionExample();
        System.out.println("Field value: " + field.get(obj));  // John 출력
    }
}

📌 setAccessible(true)를 사용하여 비공개 필드에 접근할 수 있음.

메서드 호출 예제

import java.lang.reflect.Method;

public class MethodReflectionExample {
    private void sayHello(String name) {
        System.out.println("Hello, " + name);
    }

    public static void main(String[] args) throws Exception {
        Method method = MethodReflectionExample.class.getDeclaredMethod("sayHello", String.class);
        method.setAccessible(true);  // private 메서드 호출 허용
        MethodReflectionExample obj = new MethodReflectionExample();
        method.invoke(obj, "Java");  // Hello, Java 출력
    }
}

📌 리플렉션을 사용하여 비공개 메서드를 호출할 수 있음.

반응형

2. 상세 주제 정리

 

1. 애노테이션(Annotation) 개념

**애노테이션(Annotation)**은 소스 코드에 추가적인 정보를 제공하는 메타데이터입니다.
✔ 애노테이션은 컴파일러, 런타임, 문서화 등 다양한 목적으로 사용됩니다.
✔ 애노테이션은 코드의 동작을 변경하거나 런타임에 동적으로 처리할 수 있는 정보 제공자로 활용됩니다.
자바 표준 애노테이션에는 @Override, @Deprecated, @SuppressWarnings 등이 있습니다.

📌 애노테이션의 주요 용도
컴파일러 지시 : 코드 최적화나 경고
런타임 처리 : 리플렉션을 활용해 동적으로 처리
프레임워크에서의 활용 : 스프링이나 JPA에서 종속성 주입, 매핑 등에 사용


 

2. 애노테이션 정의 및 사용법

애노테이션은 @ 기호로 시작하며, 클래스, 메서드, 필드 등에 붙여서 사용할 수 있습니다.
✔ 애노테이션은 인자값을 가질 수도 있으며, @interface 키워드를 사용하여 정의합니다.

애노테이션 정의 예제

public @interface MyAnnotation {
    String value() default "Hello";  // 기본값 설정
}

📌 @interface를 사용하여 애노테이션을 정의할 수 있음.

애노테이션 사용 예제

public class AnnotationExample {
    @MyAnnotation(value = "Custom Value")
    public void myMethod() {
        System.out.println("This is a method.");
    }

    public static void main(String[] args) {
        try {
            Method method = AnnotationExample.class.getMethod("myMethod");
            MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
            System.out.println("Annotation Value: " + annotation.value());  // Custom Value 출력
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}

📌 리플렉션을 사용하여 런타임에 애노테이션의 값을 읽을 수 있음.


 

3. 자주 사용하는 자바 표준 애노테이션

  • @Override : 메서드 오버라이딩을 명시적으로 표시
  • @Deprecated : 더 이상 사용되지 않는 메서드, 클래스, 필드를 표시
  • @SuppressWarnings : 컴파일러 경고를 무시

@Override 예제

public class OverrideExample {
    @Override
    public String toString() {
        return "This is the overridden toString method!";
    }

    public static void main(String[] args) {
        OverrideExample obj = new OverrideExample();
        System.out.println(obj.toString());  // This is the overridden toString method!
    }
}

📌 @Override는 메서드를 오버라이딩할 때 필수적으로 사용해야 하며, 잘못된 오버라이딩을 방지


4. 리플렉션과 애노테이션 결합 활용

리플렉션과 애노테이션을 결합하여 특정 애노테이션이 붙은 클래스나 메서드를 동적으로 처리할 수 있습니다.

리플렉션과 애노테이션 결합 예제

import java.lang.annotation.*;
import java.lang.reflect.*;

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    String value();
}

public class ReflectionAnnotationExample {
    @MyAnnotation(value = "Custom Annotation")
    public void myMethod() {
        System.out.println("Method executed.");
    }

    public static void main(String[] args) {
        try {
            Method method = ReflectionAnnotationExample.class.getMethod("myMethod");

            // 애노테이션이 존재하면 처리
            if (method.isAnnotationPresent(MyAnnotation.class)) {
                MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
                System.out.println("Annotation Value: " + annotation.value());  // Custom Annotation 출력
            }

            method.invoke(new ReflectionAnnotationExample());  // Method executed.
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

📌 리플렉션을 활용하여 애노테이션이 붙은 메서드를 찾아 동적으로 처리


지금까지 리플렉션과 애노테이션에 대해 배웠어요!
👉 "이제 Java 성능 최적화 및 메모리 관리에 대해 배우고 싶다면?"
다음 회차에서 성능 최적화 및 메모리 관리에 대해 다뤄봅시다!

반응형