【问题标题】:Nested reified parameter not working to create a ParameterizedTypeReference嵌套的具体化参数无法创建 ParameterizedTypeReference
【发布时间】:2018-10-22 08:25:15
【问题描述】:

我有以下内联函数和一个具体化的参数来概括一个 http 资源获取:

inline fun <reified N> getResources(): ResponseEntity<List<N>> {
    val httpEntity = HttpEntity(null, httpHeaders)
    val resourceStr = getResourceString<N>()
    return rest.exchange(testContext.baseUrl + "/api/v1/$resourceStr", HttpMethod.GET,
            httpEntity, typeRef<List<N>>())
}

我正在构建 ParameterizedTypeReferencetypeRef 支持功能,如回答 here

inline fun <reified T : Any> typeRef(): ParameterizedTypeReference<T>{
    return object : ParameterizedTypeReference<T>() {}
} 

当调用getResources&lt;Employee&gt;()时,构建的ParameterizedTypeReferenceParameterizedTypeReference.type.actualTypeArguments包含java.util.List&lt;? extends N&gt;而不是java.util.List&lt;Employee&gt;

请注意,我将 typeRef&lt;List&lt;N&gt;&gt;(其中 N 已具体化)从 getResources() 传递到 typeRef() 预期的具体化类型 T,但它似乎无法正确构建其类型。

为什么这不起作用?有什么解决办法吗?

更新:

我已将代码重构为在第一个内联函数中直接构建 ParameterizedTypeReference,但我仍将其作为 java.util.List&lt;? extends N&gt;

private inline fun <reified N> getResources(): ResponseEntity<List<N>> {
    val httpEntity = HttpEntity(null, httpHeaders)
    val resourceStr = getResourceString<N>()
    return rest.exchange(testContext.baseUrl + "/api/v1/$resourceStr", HttpMethod.GET,
            httpEntity, object : ParameterizedTypeReference<List<N>>() {})
}

【问题讨论】:

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


    【解决方案1】:

    似乎 Kotlin 不支持将具体参数用作泛型类型。

    为了解决这个问题,我使用 Guava 生成一个 Type 对象并手动构建 ParameterizedTypeReference:

    private fun <T : Any> listTypeRef(clazz: Class<T>): ParameterizedTypeReference<List<T>> {
        val type = TypeToken.of(clazz).type
        val make = ParameterizedTypeImpl.make(List::class.java, arrayOf(type), null)
        return ParameterizedTypeReference.forType<T>(make) as ParameterizedTypeReference<List<T>>
    }
    

    那我就在getResources()函数中使用,传递嵌套类型的java类(S::class.java):

    inline fun <reified S : Any> getResources(): ResponseEntity<List<S>> {
        val httpEntity = HttpEntity(null, httpHeaders)
        val resourceStr = getResourceString<S>(null)
        return rest.exchange(testContext.baseUrl + "/api/v1/$resourceStr", HttpMethod.GET,
                httpEntity, listTypeRef(S::class.java))
    }
    

    【讨论】:

      猜你喜欢
      • 2012-07-17
      • 2021-07-06
      • 2011-06-18
      • 1970-01-01
      • 1970-01-01
      • 2023-02-06
      • 2015-01-11
      • 2011-01-27
      • 2013-12-30
      相关资源
      最近更新 更多