Reflection?
리플렉션은 자바 기능 중 하나로, 클래스나 인터페이스의 정보에 직접 접근할 수 있도록 하는 API이다.
private 변수나, 함수, 생성자 등의 정보에 접근이 가능하다.
테스트 클래스
class SampleClass private constructor(private val privateInt : Int, private val privateString: String) {
private var privateField: Boolean = true
private fun privateFunction(): Boolean {
return false
}
}
위의 코드와 함께 설명하려 한다.
코드를 보면 생성자, 변수, 함수 죄다 private이다.
리플렉션을 통해서 생성하고, 변수를 조작하고, 함수를 실행해 보겠다.
클래스 가져오기
val c = Class.forName("com.onetwothree.reflectionteest.SampleClass")
Class.forName
를 이용하면 클래스 정보를 가져올 수 있다.
인자로는 해당 패키 지명을 포함한 클래스의 풀네임을 넣어주면 된다.
클래스 생성하기
val constructor = c.getDeclaredConstructor(Int::class.java, String::class.java)
val sampleClass = constructor.newInstance(5,"Five")
c.getConstructor
, c.getDeclaredConstructor
함수를 사용해서 생성자를 가져올 수 있다.
생성자가 private 이기 때문에 getDeclaredConstructor를 사용해야 한다.
인자로 해당 생성자가 실제로 사용하는 인자 타입을 넣어줘야 한다.
결과로 얻은 constructor의 newInstance
함수에 인자를 넣으면 해당 클래스를 생성할 수 있다.
변수 가져오기
val field = c.getDeclaredField("privateField")
val modifier = Modifier.toString(field.modifiers)
field.isAccessible = true
field.set(sampleClass, false)
val privateField = field.get(sampleClass) as Boolean
getDeclaredField
를 통해서 변수 필드를 가져올 수 있다.
private 이기 때문에 해당 필드를 사용하려면 isAccessible
를 통해서 액세스 가능하도록 해주어야 한다.
set
함수를 통해서 변수를 세팅할 수 있다.
인자로는 변수를 세팅할 대상 인스턴스와 값을 넣으면 된다.
예제에서는 인 스터 스는 위에서 만든 sampleClass를 넣고 값을 false를 주었다.
get
함수를 통해서 변수를 가져올 수 도 있다.
인자로 가져올 대상인 인스턴스를 넣으면 값을 주는데 타입은 지정이 안되기에 직접 변환해서 사용하면 된다.
modifiers
를 이용하면 대상 필드의 접근제어자를 확인할 수도 있다.
함수 사용하기
val method = c.getDeclaredMethod("privateFunction")
method.isAccessible = true
val privateFunction = method.invoke(sampleClass) as Boolean
함수를 사용하고 싶을 땐 getDeclaredMethod
를 사용하면 된다.
역시나 private 이기에 isAccessible
를 true로 주어야 한다,
invoke
함수로 대상 클래스의 함수를 호출할 수 있다.
역시나 결과 타입은 직접 변환해주면 된다.
'안드로이드' 카테고리의 다른 글
Android - java.time 패키지 (0) | 2020.07.15 |
---|---|
Android Hilt - WorkManager (0) | 2020.07.03 |
Android & Java - Dynamic Proxy (0) | 2020.06.30 |
Android Espresso #4 - ActivityRules (0) | 2020.06.29 |
Android Espresso #3 - RecyclerView (0) | 2020.06.26 |