Kotlin 반사

10491 단어 Kotlinreflection

자기소개


iOS(iOS 이상)와 안드로이드 응용 프로그램의 엔지니어.
반년은 주로 안드로이드였다.
나는 Oisix에서 일한다.

개요


Java 등 언어별 반사 기능을 갖춘 Kotlin 버전입니다.
클래스 구조 (예: 속성) 를 읽거나 다시 쓰는 기능입니다.KClass(클래스 참조), KProperty(속성 참조)를 사용합니다.

프로젝트 설정


kotlin 표준 라이브러리 (kotlin-stdlib-xx) 에 포함되지 않았기 때문에 (파일 크기를 줄이기 위해) app/build.gradle에 다음 내용을 추가합니다.

dependencies {
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
}

※ 위의 내용이 없더라도 반사는 구축 오류를 일으키지 않지만 반환값이나 출력 오류 로그가 없습니다.

file size


kotlin-reflect의 크기는 4.8KB입니다.

Class References


Kotlin의 클래스 참조는 KClass 유형입니다.
data class User(val firstName: String, var lastName: String,private val secretName: String)

val user = User("Test", "Debug", "Hoge")

val c:KClass<User> = User::class
.java면 Java class reference를 받을 수 있습니다.
val j:Class<User> = User::class

Kotlin Class 참조에서 속성 가져오기

val kClass = User::class
kClass.memberProperties.forEach { p ->
   Log.d(TAG, p.name + ":" + p.get(user))
}
사용자 클래스가 개인 속성을 가지고 있다면, 호출 액세스 Exception이throw에 의해 호출됩니다.
val kClass = User::class
kClass.memberProperties.forEach { p ->
    try {
        Log.d(TAG, p.name + ":" + p.get(user))
    } catch (e: IllegalCallableAccessException) {
        Log.d(TAG, p.name + " is private property.")
    }
}
isAccessible=true이면 private의 property(java와 동일)를 참조할 수 있습니다
val kClass = User::class
kClass.memberProperties.forEach { p ->
    try {
         p.isAccessible = true//これを設定すると、privateなpropertyも参照できる
        Log.d(TAG, p.name + ":" + p.get(user))
    } catch (e:Throwable) {
        e.printStackTrace()
    }
}
Java 클래스 참조에서 속성 가져오기
val javaClass = User::class.java
javaClass.declaredFields.forEach { field ->
    field.isAccessible = true
    Log.d(TAG, field.name + ":" + field.get(user))
}

Property References


클래스 이름: 속성 이름은 속성 인용입니다.
KProperty형

val firstName = User::firstName.get(user)
val javaGetter = User::firstName.javaGetter//ゲッターメソッド(Method型)。public final getFirstName() 
val javaField = User::firstName.javaField//Field(Field型)。private final firstName 

User::lastName.set(user, "lastNameDebug")//これで値できるセット

val sercretName = User::sercretName.get(user)//コンパイルエラー。private fieldはこの方法では参照できない


실제로 속성을 얻었을 때 다음 p는 KProperty1<속성을 가진 클래스, 속성의 유형>(KProperty에서 파생된)의 KProperty1Impl 클래스(내부에서 자동으로 생성된 클래스)를 실현했다.
변경 가능한 속성은 KMutableProperty1Impl 클래스입니다.
val kClass = User::class
kClass.memberProperties.forEach { p:KProperty1<User, *> ->
    try {
        p.isAccessible = true//これを設定すると、privateなpropertyも参照できる
        Log.d(TAG, p.name + ":" + p.get(user))
    } catch (e:Throwable) {
        e.printStackTrace()
    }
}
KProperty의 파생 인터페이스는 다음과 같은 세 가지가 있습니다.
또한 각 인터페이스에는 MutableProperty1(KMutableProperty1)
  • KProperty0:java류의static 변수를 얻을 때 이용한다
  • KProperty1: 앞에서 설명한 바와 같이.구성원 속성을 가져올 때 사용합니다
  • KProperty2: 확장 속성을 가져올 때 사용합니다
  • 총결산

  • 속성 주변은 Java와 같은 느낌으로 접근할 수 있습니다
  • 디버깅할 때의 클래스 내용 출력 등에 사용할 수 있다
  • Function References 등 다른 반사 기능도 많다
  • apk 사이즈가 클수록 고려해 보는 것이 좋습니다
  • 조용히 들어주셔서 감사합니다.

    좋은 웹페이지 즐겨찾기