2017-10-02 4 views
0

Le code ci-dessous concerne la réflexion. Il essaie de faire 2 choses:Comment obtenir la référence de classe de KParameter dans kotlin?

  1. case1() crée une instance de classe SimpleStudent, cela fonctionne.
  2. case2() crée une instance à partir de Student classe, ne fonctionne pas.

La raison pour laquelle case2() fonctionne pas aussi bien que la question est que l'intérieur de cette generateValue():

  1. Je ne sais pas comment le vérifier est le type Kotlin ou mon propre type (j'ai sale moyen de vérifier param.type.toString() not contain "kotlin" mais je me demande s'il y a une meilleure solution
  2. Je ne sais pas comment obtenir sa référence de classe quand il s'agit d'une classe personnalisée.Le problème est que même si param.type.toString() == "Lesson", quand j'ai essayé d'obtenir param.type::class, il est class kotlin.reflect.jvm.internal.KTypeImpl

Alors, comment le résoudre? Merci

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

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() 
} 

Répondre

1

Problème résolu:

Vous pourriez obtenir ce ::class en utilisant param.type.classifier as KClass<T>param is KParameter