从Moshi类型适配器的通用化类型中获取ParameterizedType

tyn*_*ynn 6 generics android kotlin moshi kotlin-reified-type-parameters

给定的断言由于错误而失败

找不到为类GenericType生成的JsonAdapter构造函数

我如何从物化类型的正确类型TMoshi

GenericType类型标注有@JsonClass(generateAdapter = true)使用科特林代码生成的莫希仅使用Moshi.Builder().build()

我可以ParameterizedType手动生成

Types.newParameterizedType(GenericType::class.java, String::class.java)
Run Code Online (Sandbox Code Playgroud)

在哪里GenericType::class.java给出T:class.java。但是我不知道如何获取String类型参数来泛化该方法。

inline fun <reified T : Any> adapter() =
    moshi.adapter<T>(type<T>())

inline fun <reified T : Any> type() =
    T::class.java

assert(adapter<GenericType<String>>() != null)
Run Code Online (Sandbox Code Playgroud)

请注意,该适配器可用于任何GenericType<T>,但不适用于GenericType::class.java没有通用信息的实际类。

因此genericType,只要我知道以下内容,就可以找到适配器G

inline fun <reified G : Any> genericType() =
    newParameterizedType(GenericType::class.java, G::class.java)
Run Code Online (Sandbox Code Playgroud)

G就是我希望找到的type(),因为T::class.java 只有GenericType::class.java在那里。

tyn*_*ynn 5

我现在正在使用TypeToken类似于Gson的自定义方法实现我的目标

abstract class TypeToken<T>

inline fun <reified T : Any> type() = object : TypeToken<T>() {}::class
      .java
      .genericSuperclass
      .let { it as ParameterizedType }
      .actualTypeArguments
      .first()
Run Code Online (Sandbox Code Playgroud)

但我仍然希望找到一种方法来直接获取ParameterizedTypefrom T


tyn*_*ynn 1

Kotlin 现在提供了一个实验性typeOf<T>()函数来返回KType具体化类型的T。所以所需的代码很简单:

inline fun <reified T : Any> type() = typeOf<T>()
Run Code Online (Sandbox Code Playgroud)