Обозначенные дженериками Котлин не сохраняют тип, как планировалось
Я создаю систему 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
используется здесь.
Ответы
Ответ 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>