개발일기장

Reflection ... 본문

JAVA

Reflection ...

게슬 2023. 11. 26. 14:52
728x90

일단 class를 이렇게 만들어 둠

    static class Hello{
        private Integer iValue = 10;
        public String sValue = "hello";

        public String callA(String args){
            log.info("call A");
            return "A "+args;
        }
        public String callB(String args){
            log.info("call B");
            return "B";
        }
    }

1. Class 정보 호출

 // Class 정보 획득
Class<?> classHello = Class.forName("hello.proxy.jdkdynamic.ReflectionTest$Hello");
// 내부에 있는 경우 $

 

이렇게 하면 해당 파일에 위치한 class의 meta 정보를 가지고 올 수 있다.

Class<? extends Hello> aClass = target.getClass();

또는 그냥 이렇게 getClass를 호출해도 상관 없다.

 


2. Method 호출

위에서 호출한 class의 메타 정보를 통해서 method도 호출 할 수 있다.

Method methodCallA = classHello.getMethod("callA");

Method methodCallB = classHello.getMethod("callB", String.class);
// 해당 method의 parameter로 넘겨줄 값의 type도 class로 넣어줘야함.

 

이렇게 가지고온 method의 meta정보를 통해 invoke(수행할 객체, args)로 실행시킨다.

Method methodCallB = classHello.getMethod("callB", String.class);
Object B = methodCallB.invoke(target, "456");

 


3. Field 

class meta정보를 통해 field도 사용할 수 있다.

        Field field1 = target.getClass().getDeclaredField("iValue");
        field1.setAccessible(true);
        // field1.setAccessible(false); -- > private 필드인 경우 접근 불가.
        field1.set(target, 20);
        log.info("value={}",field1.get(target));

        Field field2 = target.getClass().getDeclaredField("sValue");
        field1.setAccessible(true);
        log.info("value={}",field2.get(target));

 


일단 reflection은 동적으로 class / method / field를 조작할 수 있기 때문에 편리한 도구이지만.

Runtime 시점에 결정이 나기 때문에 에러가 발생 할 여지가 많고, compile 시점에 에러를 확인 할 수 없음..

 

정말 필요할 때만 사용하기

728x90
Comments