-
[Java] Reflection(리플렉션)프로그래밍/Java 2021. 12. 29. 16:24반응형
이 글은 혼자 학습한 내용을 바탕으로 작성되었습니다.
틀리거나 잘못된 정보가 있을 수 있습니다.
댓글로 알려주시면 수정하도록 하겠습니다.
1. Reflection이란
리플렉션이란 런타임 시점에 자바 코드 자체를 추상화하여 구체적인 클래스의 타입을 알지 못하여도 메소드나 속성 등 여러가지 작업들을 할 수 있도록 해주는 Java API 입니다.
2. Reflection을 사용하는 기술
- Spring Framework
- Jackson
- Hibernate
3. Reflection 사용 방법
forName 메소드
Class<?> couponClass = Class.forName(패키지.클래스명);
Class.forName 메소드를 이용하여 Class Object를 가져올 수 있습니다.
forName 메소드의 파라미터로 패키지를 포함한 Class 명을 전달하면 해당 Class의 Class Object를 반환하여 줍니다.
만약 패키지를 포함하지 않고 Class명만 파라미터로 전달 시 ClassNotFoundException이 Throw 됩니다.
'Object'.class
다른 방법으로는 .class를 이용하여 Class Object를 가져오는 방법이 있습니다.
getConstructors, getConstructor 메소드
모든 생성자는 Public으로 정의된 생성자만 가져올 수 있습니다.
'ClassObject'.getConstructors();
forName의 Class Object의 getConstructors 메소드를 통해 해당 Class의 정의되어 있는 모든 생성자를 가져올 수 있습니다.
모든 생성자 메소드를 반환하므로 반환 타입은 Constructor[] 타입으로 반환 됩니다.
'ClassObject'.getConstructor(생성자 파라미터 타입);
forName으로 생성된 Class Object의 getConstructor 메소드는 여러 생성자들 중 파라미터로 전달한 타입들이 맞는 생성자 1개를 반환합니다.
Package를 포함한 경우와 Class명만 전달한 경우에 대한 Test입니다.
Class명만 전달한 경우는 ClassNotFoundException이 발생하는 것을 알 수 있으며 Package를 포함한 경우는 정상적으로 Class Object를 가져오는 것을 확인할 수 있습니다.
getMethods, getMethod 메소드
모든 메소드는 Public으로 정의된 메소드만 가져올 수 있습니다.
'ClassObject'.getMethods();
forName의 Class Object의 getMethods 메소드를 통해 해당 Class에 정의되어 있는 모든 메소드들을 가져올 수 있습니다.
또한 getMethods 메소드는 Super Class의 메소드도 포함하여 반환 됩니다.
Super Class의 메소드도 포함 되기 때문에 Java의 최상단인 Object Class에 포함되어 있는 메소드는 항상 포함되어 반환 됩니다.
※ Object Class
- wait
- equals
- toString
- hashCode
- getClass
- notify
- notifyAll
위 메소드 들이 포함되어 반환 됩니다.
정의된 모든 메소드를 반환하므로 반환 타입은 Method[] 타입으로 반환 됩니다.
'ClassObject'.getMethod(메소드명, 메소드파라미터 타입);
forName으로 생성된 Class Object의 getMethod 메소드는 여러 메소드들 중 파라미터로 전달한 메소드명과 파라미터 타입이 맞는 메소드 1개를 반환합니다.
Coupon Class는 생성자를 제외한 메소드는 총 7개 선언되어 있습니다.
Coupon Class의 경우 총 7개의 메소드가 선언되어 있지만 테스트 결과를 보면 총 16개의 메소드가 반환된 것을 확인할 수 있습니다. 이건 Java의 모든 Class의 최상위 Class인 Object Class가 상속되어 있기 때문에 Object Class의 9개 메소드가 포함되어 반환 된 것입니다.
getMethod는 반환 받고자 하는 Method의 명칭과 해당 Method의 파라미터 타입을 통해 해당 Method를 찾아 반환 해 줍니다. 테스트는 getDiscountAmount 메소드를 반환 받고자 하였으면 해당 메소드의 파라미터인 productPrice가 int 타입이므로 int.class를 전달 합니다.
getMethod는 정의되지 않는 Method명을 전달 시 NoSuchMethodException을 Throw하는 것을 확인할 수 있습니다.
getFields, getField 메소드
모든 필드는 Public으로 정의된 필드만 가져올 수 있습니다.
'ClassObject'.getFields()
forName의 Class Object의 getFields 메소드를 통해 해당 Class의 정의되어 있는 모든 필드를 가져올 수 있습니다.
모든 필드를 반환하므로 반환 타입은 Field[] 타입으로 반환 됩니다.
'ClassObject'.getField(필드명)
forName으로 생성된 Class Object의 getField 메소드는 여러 필드들 중 파라미터로 전달한 필드명과 동일한 필드 1개를 반환합니다.
Coupon Class는 name필드만 Public으로 가지고 있습니다.
필드가 Public인 경우와 Private인 경우에 대한 Test입니다.
getFields의 경우 정의된 여러 필드 중 Public 필드는 name 하나 이므로 1개의 Field를 담은 배열이 반환됩니다.
getField메소드를 통해 name필드를 가져온 경우 또한 name이 Public으로 선언되어 정상적으로 반환되는 것을 확인 할 수 있습니다.
이번에는 Private으로 선언된 discount의 경우 NoSuchFieldException이 Throw되는 것을 확인할 수 있습니다.
사용된 예제 코드는 Git에 있습니다.
반응형'프로그래밍 > Java' 카테고리의 다른 글
[Java] toString 메소드 재정의 (0) 2022.03.03 [Java] Reflection Private (0) 2022.01.11 [Java] Reflection Invoke (0) 2021.12.31 [Java] 트랜잭션 (0) 2021.11.13