Back-end/Java, Kotlin

Reflection : 그누므 리플렉션이 모야 !! (ft. 애노떼이숀, 쩨네릭)

philo0407 2021. 4. 8. 21:26

주위에서 하두 리플렉션 얘기를 많이 들어서 이참에 한번 보기로 햇다.

 

5초식 리플렉션을 이용한 리팩토링 완성ㅎ - 자바로 PC방 프로그램만들기 (opentutorials.org)

 

5초식 리플렉션을 이용한 리팩토링 완성ㅎ - 자바로 PC방 프로그램만들기

ㅎㅎ 이것도 곧 올리겠습니다. 리플렉션을 어떻게 설명할까하다가.. 지쳐가지고 중간에 업로딩을 안했었거든요. ㅠㅠ  제작에 꼭 필요한 부분은 아니지만, 리팩토링하다가 재밌어서 올려봅니

opentutorials.org

(참고 !! - 감사합니다 ㅎㅎ) 

 

한 클래스가 다른 클래스의 정보를 열람할 수 있는 것을 말한다.

 

이게 가능한 이유는 컴파일 후에 바이트코드가 static영역에 저장되는데

클래스 이름을 안다면 이 영역을 조사하여 알아낼 수 있다는 것이다.

 

package test.grammer.reflection;

public class RefObject {

  private int numId;
  private int name;

  public int getNumId() {
    return numId;
  }

  public void setNumId(int numId) {
    this.numId = numId;
  }
}

 

package test.grammer.reflection;

import static java.lang.System.*;

import java.lang.reflect.Field;

public class ReflectionUser {

  public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
    Class<?> clazz = RefObject.class;

    out.println("clazz.getCanonicalName() = " + clazz.getCanonicalName());
    out.println("clazz.getDeclaredFields() = " + clazz.getDeclaredFields());

    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields) {
      out.println("field.getName() = " + field.getName());
    }

    Field field = clazz.getDeclaredField("numId");

    RefObject refObject = new RefObject();

    field.setAccessible(true);
    int numId = (int) field.get(refObject);
    out.println("numId = " + numId);
  }

}

 

위를 실행하면 아래와 같은 에러가 뜬다.

 

 

하지만 이것 또한 접근할 수 있다.

field.setAccessible(true);

위 코드를 추가해 주면 된다.

 

field.set(refObject, 3);
numId = (int) field.get(refObject);
out.println("numId = " + numId);

위처럼 변수를 셋팅하면 셋팅된 값이 들어온다.

 

 

제네릭

와일드카드 ? 란

List ~ ArrayList 가 가지는 다형성 관계처럼

ArrayList<Product> list  = new ArrayList<Tv>();

위와 같은 선인이 가능하게 해준다.

기존의 T, E 등의 알파벳 표기는 항상 짝을 이뤄야 했다.

 

 

 

애너테이션

 

RetentionPolicy

1. SOURCE  : source 레벨까지만

2. CLASS  :  source, 클라쓰 레벨까지만

3. RUNTIME : source, 클라쓰, RUNTIME 레벨까지 지원

 

** 보통 1, 3번이 많이 사용된다.

 

 

@interface ~ {

 ...

}

 

위와 같이 선언한다.