Kotlin reified仿制药没有按计划保留类型

时间:2018-06-14 05:33:39

标签: generics kotlin kotlin-reified-type-parameters

我正在创建一个类似于Gson的类似TypeToken的系统,我偶然发现了一些我不理解的东西。

这段代码的意图是只有一个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)没有“真正”内联并且生成了一些中间名称。

我也看过docs,但我没有找到相关的例子。

我如何创建我最初打算做的事情?为什么会这样?

编辑:

我想创建一个问题,但他们已经知道了这个问题。

发布了一个非常类似的问题here,据称是this的重复问题。您也可以在后一个链接中投票。

供将来参考:此处使用Kotlin 1.2.50

1 个答案:

答案 0 :(得分:3)

我反编译这段代码,发现两个func之间有一些区别

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>