johann
johann

Reputation: 1135

Generic issue on kotlin

I'm trying to implement a basic function for handling external API calls :

   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)
        }

    }

The way I'm calling it is pretty straightforward :

 api.get<SWObject>(Utils.SW_API)

When trying to execute that code, I get a cast exception :

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

Object returned is not an instance of the SWObject class but a LinkedHashMap. I'm still struggling with reified or inline keyword, sorry if my implementation doesn't follow the best practices.

Upvotes: 1

Views: 478

Answers (1)

jsamol
jsamol

Reputation: 3232

Use T::class.java instead of T::class in the exchange method and remove the explicit type argument Any from the exchange method invocation as it became unnecessary. You also don't need to cast the response body to 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 returns a Kotlin class (KClass) while Object::class.java returns a Java class (Class) and is equivalent to Java's Object.class. Note that KClass is not the same as Class.

The exchange method just expects its responseType argument to be the type of Class (or ParametrizedTypeReference but that's not the case for that).

Upvotes: 2

Related Questions