Обозначенные дженериками Котлин не сохраняют тип, как планировалось - программирование
Подтвердить что ты не робот

Обозначенные дженериками Котлин не сохраняют тип, как планировалось

Я создаю систему TypeToken -like, похожую на то, что имеет Gson, и я наткнулся на то, что я не понимаю.

Намерение с этим кодом было бы иметь только один класс TypeReference с одним общим аргументом, который мог бы содержать несколько. Класс будет создан с использованием inline функции, таким образом, пользователю не нужно знать класс Holder.

Пожалуйста, рассмотрите приведенный ниже код:

package testing

import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type

abstract class TypeReference<T : Holder> {
    val type: Type = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0]

    override fun toString(): String {
        return type.typeName
    }
}

inline fun <reified T : Holder> create() = object : TypeReference<T>() {}

inline fun <reified WHAT> createSingle() = object : TypeReference<Single<WHAT>>() {}

class Foo

interface Holder

interface Single<T> : Holder

fun main(args: Array<String>) {
    println(create<Single<HashMap<Int, String>>>())
    println(create<Single<Foo>>())

    println(createSingle<HashMap<Int, String>>())
    println(createSingle<Foo>())
}

Это результат:

testing.Single<java.util.HashMap<java.lang.Integer, java.lang.String>>
testing.Single<testing.Foo>
testing.Single<WHAT>
testing.Single<WHAT>

Мне кажется, что Single<WHAT> (sry для этого родового имени) не получает "по-настоящему" inlined, а некоторое промежуточное имя генерируется.

Я также просмотрел документы, но я не нашел примеров относительно этого.

Как я могу создать то, что я изначально намеревался сделать? Почему это происходит?

Редактировать.:

Я хотел создать проблему, но они уже знают об этом.

Очень похожая проблема выдается здесь, который называется повторяющееся из этого. Вы также можете проголосовать по последней ссылке.

Для справок: Kotlin 1.2.50 используется здесь.

4b9b3361

Ответ 1

Я декомпилирую этот код, нашел несколько разных между двумя функциями

private static final TypeReference create() {
  Intrinsics.needClassReification();                 <---- here
  return (TypeReference)(new TypeReference() {
  });
}

private static final TypeReference createSingle() {
  return (TypeReference)(new TypeReference() {
  });
}

И ручной добавьте этот код, отлично работайте. Не знаю слишком много об этом, документа не найдено.

inline fun <reified WHAT > createSingle() = Intrinsics.needClassReification().let {
    object : TypeReference<Single<WHAT>>() {}
}

результат:

Single<java.util.HashMap<java.lang.Integer, java.lang.String>>

Single<Foo>

Single<java.util.HashMap<java.lang.Integer, java.lang.String>>

Single<Foo>