2017-10-02 1 views
0

아래 코드는 리플렉션에 대한 것입니다. 그것은 두 가지 작업을 시도 :kotlin의 KParameter에서 클래스 참조를 가져 오는 방법은 무엇입니까?

  1. case1()SimpleStudent 클래스에서 인스턴스를 생성을, 그것을 작동합니다.
  2. case2()은 작동하지 않는 Student 클래스의 인스턴스를 만듭니다.

    1. 나는 그것이 코 틀린 유형 또는 내 자신의 유형 (나는이입니다 확인하는 방법을 모른다 :

    case2() 질문뿐만 아니라 작동하지 이유는, generateValue() 그 내부에 있다는 것입니다 더러운 방법을 param.type.toString() not contain "kotlin" 확인하지만 더 나은 솔루션이 있을지 궁금하다.

  3. 사용자 정의 클래스의 클래스 참조를 얻는 방법을 모르겠다. 때, 내가 param.type::class을 얻으려고했을 때 문제가있다. class kotlin.reflect.jvm.internal.KTypeImpl

그래서 어떻게 해결할 수 있습니까? 감사합니다

==============

import kotlin.reflect.KParameter 
import kotlin.reflect.full.primaryConstructor 
import kotlin.test.assertEquals 

data class Lesson(val title:String, val length:Int) 
data class Student(val name:String, val major:Lesson) 
data class SimpleStudent(val name:String, val age:Int) 

fun generateValue(param:KParameter, originalValue:Map<*,*>):Any? { 
    var value = originalValue[param.name] 

// if (param.type is not Kotlin type){ 
//  // Get its ::class so that we could create the instance of it, here, I mean Lesson class? 
// } 

    return value 
} 

fun case1(){ 
    val classDesc = SimpleStudent::class 
    val constructor = classDesc.primaryConstructor!! 

    val value = mapOf<Any,Any>(
      "name" to "Tom", 
      "age" to 16 
    ) 

    val params = constructor.parameters.associateBy (
     {it}, 
     {generateValue(it, value)} 
    ) 

    val result:SimpleStudent = constructor.callBy(params) 

    assertEquals("Tom", result.name) 
    assertEquals(16, result.age) 
} 

fun case2(){ 
    val classDesc = Student::class 
    val constructor = classDesc.primaryConstructor!! 

    val value = mapOf<Any,Any>(
      "name" to "Tom", 
      "major" to mapOf<Any,Any>(
        "title" to "CS", 
        "length" to 16 
      ) 
    ) 

    val params = constructor.parameters.associateBy (
     {it}, 
     {generateValue(it, value)} 
    ) 

    val result:Student = constructor.callBy(params) 

    assertEquals("Tom", result.name) 
    assertEquals(Lesson::class, result.major::class) 
    assertEquals("CS", result.major.title) 
} 

fun main(args : Array<String>) { 
    case1() 
    case2() 
} 

답변

1

문제 해결 :

당신이 얻을 수있는 ::classparam.type.classifier as KClass<T>param is KParameter

를 사용하여
관련 문제