Develop

19일차_Annotation, Reflection, Front(HTML) 본문

백엔드/KDT_Programmers

19일차_Annotation, Reflection, Front(HTML)

230801 2025. 3. 31. 23:28

250328(금)

 

안녕하세요!

오늘은 19일차(4주 5일차) 입니다.

 

 

금요일에는 어노테이션을 정의하고, 클래스에서 사용하고, 리플렉션을 이용해 어노테이션을 분석하고 호출하는 코드를 학습했습니다.

어노테이션과 리플렉션에 대해 이론 복습해보겠습니다.

 

Annotation

  • 정의
    annotation 은 자바코드에 추가정보를 표시하기 위한 특수한 주석으로, '@' 기호로 시작하는 태그를 이용해 사용함
  • 예를들어 '@Test' 는 이 메서드를 테스트해야 한다는 것을 프로그램에 알릴 뿐, 주석처럼 프로그램 자체에는 아무런 영향을 미치지 않는다. (컴파일러나 런타임에서 이 정보를 활용해서 어떤 처리를 하게 할 수 있음)
  • 종류
    • 표준 어노테이션 : 자바에서 기본적으로 제공하는 어노테이션
      ex) @Override, @Deprecated, @SupperessWarnings, @SafeVarargs, @FunctionalInterface, @Native등

    • 사용자 정의 어노테이션 : 개발자가 필요에 따라 정의한 어노테이션

    • 메타 어노테이션 : 어노테이션을 정의하는데 사용되는 어노테이션 (어노테이션의 어노테이션)
      • @Target : 어노테이션이 적용될 수 있는 대상 (ex. 클래스, 메서드, 필드 등)
      • @Retention : 어노테이션이 유지되는 범위 지정(ex. 컴파일 후, 실행중)
      • @Documented : API 문서(javadoc) 에 어노테이션 설명 포함여부
      • @Inherited : 부모 클래스에 있는 어노테이션이 자식 클래스에도 상속될지 여부
      • @Repeatable : 같은 어노테이션을 여러번 붙일 수 있게 할지 여부


  • 어노테이션 만들기 & 사용
// annotation 만들기
@Retention(RetentionPolicy.RUNTIME)  // annotation 정보를 런타임에도 사용할 수 있게 유지
@Target(ElementType.METHOD)          // 메서드에만 사용가능
public @interface Test {
// 요소 없음(마커 어노테이션)
}


// annotation 사용하기
public class MyTestClass {

    @Test
    public void shouldRun() {
        System.out.println("이 메서드는 테스트 대상입니다.");
    }

    public void notTest() {
        System.out.println("이건 그냥 일반 메서드.");
    }
}

 


 

Reflection

쓰임

  1. 의존성 주입-reflection은 코드를 실행중간에 분석하거나 조작할 수 있게 해주는 기능
  2. 어노테이션 기반 동작 -reflection은 특정 annotation이 붙은 메서드를 골라서 실행하는 도구
  3. 캡슐화 우회-객체의 캡슐화를 우회해서 내부 필드값을 동적으로 변경하거나 읽을 수 있게함
  4. 자동화 처리-DB, JSON -> 객체 필드 매핑
 
  • 예제 클래스
public class Person {
    private String name = "홍길동";

    public void sayHello() {
        System.out.println("안녕하세요, " + name + "입니다.");
    }
}

 

  • 리플렉션 예제
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectionExample {
    public static void main(String[] args) throws Exception {
        // 1. 클래스 객체 가져오기
        Class<?> clazz = Person.class;

        // 2. 인스턴스 생성
        Object obj = clazz.getDeclaredConstructor().newInstance();

        // 3. 필드 접근 (private 필드도 가능)
        Field nameField = clazz.getDeclaredField("name");
        nameField.setAccessible(true); // private 필드 접근 허용
        nameField.set(obj, "이순신");   // 필드 값 변경

        // 4. 메서드 가져오기
        Method method = clazz.getDeclaredMethod("sayHello");

        // 5. 메서드 실행
        method.invoke(obj); // 출력: 안녕하세요, 이순신입니다.
    }
}

 

1. 어떤 타입의 클래스가 올지 모르기 때문에 Class<?>로 타입을 제한하지 않고 받아준다.

2. 인스턴스는 공통 조상 클래스인 Object 타입으로 생성한다.

3. setAccessible(true)로 접근 제한을 해제한 후, set() 메서드를 사용해 필드 값을 동적으로 변경한다.

4. 메서드를 가져와 실행 가능한 형태로 만들고,

5. invoke()를 통해 해당 메서드를 실행하여 obj의 동작 결과를 출력한다.

 

 

 

감사합니다.