Java 리플렉션, 객체 복제, 제네릭 및 어노테이션

리플렉션

리플렉션 개요

리플렉션은 실행 시점에 클래스 정보를 동적으로 분석하고 객체 메서드를 호출하는 기술입니다. JVM은 각 클래스에 대해 단일 Class 객체를 생성하며, 이 객체는 클래스의 구조 정보를 포함합니다.

리플렉션 핵심 클래스

클래스기능
Class클래스 메타데이터 표현
Field클래스 필드 조작
Method메서드 실행 관리
Constructor생성자 제어
// Class 객체 획득 방법
Class<?> cls1 = Class.forName("com.example.Employee");
Class<?> cls2 = Employee.class;
Class<?> cls3 = new Employee().getClass();

리플렉션 활용 예제

public class Employee {
    private String id;
    public Employee() {}
    public Employee(String id) { this.id = id; }
}

// 생성자를 통한 객체 생성
Constructor<?> cons = Class.forName("com.example.Employee")
                             .getDeclaredConstructor(String.class);
cons.setAccessible(true);
Object obj = cons.newInstance("E123");

리플렉션 사용 시나리오

  • 프레임워크 의존성 주입
  • 동적 프록시 생성
  • 애노테이션 처리기 구현
  • 런타임 클래스 로딩

객체 생성 기법

객체 복제

얕은 복제는 참조 필드를 공유하며, 깊은 복제는 중첩 객체까지 새로 생성합니다.

class Department implements Cloneable {
    private String name;
    @Override
    protected Object clone() {
        Department dept = null;
        try { dept = (Department) super.clone(); } 
        catch (CloneNotSupportedException e) { /* 처리 */ }
        return dept;
    }
}

객체 직렬화

직렬화는 객체를 바이트 스트림으로 변환합니다. transient 필드는 직렬화에서 제외됩니다.

public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    private transient String password; // 직렬화 제외
}

제네릭

제네릭 특성

제네릭은 컴파일 시점에 타입 안정성을 제공하며, 런타임에는 타입 정보가 삭제됩니다.

제네릭 구현 방식

// 제네릭 클래스
public class DataContainer<T> {
    private T content;
    public void set(T item) { content = item; }
    public T get() { return content; }
}

// 제네릭 메서드
public <U> void processItem(U item) {
    System.out.println(item.getClass());
}

타입 경계

// 상한 경계
List<? extends Number> numList = new ArrayList<Integer>();

// 하한 경계
List<? super Integer> intList = new ArrayList<Number>();

어노테이션

메타 어노테이션

  • @Target: 적용 대상 지정
  • @Retention: 생명주기 설정
  • @Documented: 문서 포함 표시
  • @Inherited: 하위 클래스 상속

커스텀 어노테이션

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CustomRule {
    String category() default "Validation";
    int priority() default 1;
}

어노테이션 처리

Method method = targetClass.getMethod("validateData");
if (method.isAnnotationPresent(CustomRule.class)) {
    CustomRule rule = method.getAnnotation(CustomRule.class);
    System.out.println("Rule Priority: " + rule.priority());
}

태그: java 리플렉션 객체복제 제네릭 어노테이션

5월 31일 17:10에 게시됨