【问题标题】:Generic issue on kotlinkotlin 上的一般问题
【发布时间】:2019-07-23 02:21:45
【问题描述】:

我正在尝试实现一个处理外部 API 调用的基本功能:

   inline fun <reified T> get(url: String): T? {

        try {

            val restTemplate = RestTemplate()
            val response = restTemplate.exchange<Any>(
                url,
                HttpMethod.GET,
                headersForRestTemplate,
                T::class)

            return response.getBody() as T

        } catch (e: Exception) {
            log.info("Exception ::" + e.message)
            throw ServiceException(e)
        }

    }

我的称呼很简单:

 api.get<SWObject>(Utils.SW_API)

当尝试执行该代码时,我得到一个强制转换异常:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to jp.co.xx.demo.models.SWObject

返回的对象不是SWObject 类的实例,而是LinkedHashMap。我仍在为reifiedinline 关键字苦苦挣扎,如果我的实现没有遵循最佳实践,请见谅。

【问题讨论】:

    标签: spring-boot generics kotlin resttemplate


    【解决方案1】:

    exchange 方法中使用T::class.java 而不是T::class,并从exchange 方法调用中删除显式类型参数Any,因为它变得不必要了。您也不需要将响应正文转换为 T

    inline fun <reified T> get(url: String): T? {
        try {
            val restTemplate = RestTemplate()
            val response = restTemplate.exchange(
                url,
                HttpMethod.GET,
                headersForRestTemplate,
                T::class.java
            )
    
            return response.getBody()
        } catch (e: Exception) {
            log.info("Exception ::" + e.message)
            throw ServiceException(e)
        }
    }
    
    

    Object::class 返回一个 Kotlin 类 (KClass),而 Object::class.java 返回一个 Java 类 (Class),相当于 Java 的 Object.class。请注意,KClassClass 不同。

    exchange 方法只期望它的responseType 参数是Class 的类型(或ParametrizedTypeReference,但事实并非如此)。

    【讨论】:

    • 完美答案,出乎我的意料〜感谢演员提示!
    猜你喜欢
    • 1970-01-01
    • 2018-05-06
    • 1970-01-01
    • 2017-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    相关资源
    最近更新 更多