получить класс из параметров вложенного типа в kotlin - PullRequest
0 голосов
/ 26 мая 2018

У меня есть val, построенный следующим образом

val qs = hashMapOf<KProperty1<ProfileModel.PersonalInfo, *> ,Question>()

Как мне получить класс ProfileModel.PersonalInfo из этой переменной?

Другими словами, какое выражение(включая qs, конечно) должен заменить Любой , чтобы этот тест прошел.

@Test
fun obtaionResultTypeFromQuestionList(){
    val resultType = Any()
    assertEquals(ProfileModel.PersonalInfo::class, resultType)
}

Спасибо за ваше внимание

1 Ответ

0 голосов
/ 26 мая 2018

Нет прямого способа получить такую ​​информацию из-за стирания типа Java .Короче говоря - вся информация о дженериках (в вашем случае) недоступна во время выполнения, и HashMap<String, String> становится HashMap.

Но если вы сделаете некоторые изменения на уровне JVM, такие как определение нового класса, информация офактические параметры типа сохраняются.Это дает вам возможность делать некоторые хаки, как это:

val toResolve = object : HashMap<KProperty1<ProfileModel.PersonalInfo, *> ,Question>() {
    init {
        //fill your data here
    }
}

val parameterized = toResolve::class.java.genericSuperclass as ParameterizedType
val property = parameterized.actualTypeArguments[0] as ParameterizedType
print(property.actualTypeArguments[0])

печать ProfileModel.PersonalInfo.

Объяснение:

  1. Мы определяем новый анонимный класс, который влияет на уровень JVM, а не только на время выполнения, поэтому информация о generic остается
  2. Мы получаем обобщенный суперкласс нашего нового экземпляра анонимного класса, что приводит к HashMap< ... , ... >
  3. Мы получаем первымтип, который передается в HashMap общих скобках.Это дает нам KProperty1< ... , ... >
  4. Выполнить предыдущий шаг с KProperty1

Kotlin привязан к стиранию типа JVM так же, как и Java.Вы можете сделать код немного лучше, переместив создание хэш-карты в отдельную функцию:

inline fun <reified K, reified V> genericHashMapOf(
        vararg pairs: Pair<K, V>
): HashMap<K, V> = object : HashMap<K, V>() {
    init {
        putAll(pairs)
    }
}

...

val hashMap = genericHashMapOf(something to something)
...