2016-12-17 2 views
3

여기 Kotlin의 초보자입니다.Kotlin이 반사적으로 getter/setter를 호출합니다.

프로그램에서 리플렉션을 통해 개체를 만들어 채우려고합니다. 순수한 kotlin에서 동등한 기능을 찾을 수 없기 때문에 내 솔루션은 잘 작동하는 코드와 비슷하지만 java.lang.String::class.java과 intelliJ와 같은 더러운 참조를 사용해야합니다. 당연히이 점이 마음에 들지 않습니다. 이 작업을 수행하기 위해 누락 된 간단한 방법이 있습니까?

val jclass = myObject::class.java 
val setters = jclass.declaredMethods.filter { it.name.startsWith("set") } 
for (s in setters) { 
    val paramType = s.parameterTypes.first() 
    val data = when(paramType) { 
     java.lang.Integer::class.java -> foo 
     java.lang.Double::class.java -> bar 
     java.lang.String::class.java -> baz 
    } 
    s.invoke(myObject, data) 
} 

답변

7

당신은 당신의 프로젝트에 종속성으로 kotlin-reflect을 추가 할 필요 코 틀린 반사를 사용할 수 있습니다.

다른 Kotlin 버전을 사용하는 경우 kotlin-reflectfor Kotlin 1.0.5 또는 pick another version을 찾을 수 있습니다.

val properties = myObject.javaClass.kotlin.memberProperties 
for (p in properties.filterIsInstance<KMutableProperty<*>>()) { 
    val data = when (p.returnType.javaType) { 
     Int::class.javaPrimitiveType, 
     Int::class.javaObjectType -> foo 
     Double::class.javaPrimitiveType, 
     Double::class.javaObjectType -> bar 
     String::class.java -> baz 
     else -> null 
    } 
    if (data != null) 
     p.setter.call(myObject, data) 
} 

일부 세부 정보 : 다음과 같이

그 후, 당신은 당신의 코드를 다시 작성할 수 있습니다

  • 을 코 틀린 반사를 사용에도 불구하고,이 방법은 자바 클래스뿐만 아니라, 자신의 분야와 함께 작동 액세서는 here과 같이 속성으로 표시됩니다.

  • 자바 리플렉션과 마찬가지로 memberPropertiespublic이 유형과 모든 해당 수퍼 유형의 속성을 반환합니다. 유형에서 선언 된 모든 특성 (예 : private 특성을 포함하지만 수퍼 유형의 특성은 포함하지 않음)을 가져 오려면 대신 declaredMemberProperties을 사용하십시오.

  • .filterIsInstance<KMutableProperty<*>은 변경 가능한 속성 만 반환하므로 나중에 p.setter을 사용할 수 있습니다. 모든 속성의 getter를 반복해야하는 경우 제거하십시오. 무엇 코 틀린에 Int는 용도에 따라 자바 int 또는 java.lang.Integer 중 하나에 매핑 할 수 있기 때문에

  • when 블록에서 나는 Int::class.javaPrimitiveTypeInt::class.javaObjectTypep.returnType.javaType을 비교했다. Kotlin 1.1에서는 p.returnType.classifier == Int::class을 확인하는 것으로 충분합니다.

관련 문제