https://kotlinlang.org logo
#server
Title
# server
a

Alex Stelmachonak

06/28/2022, 3:35 PM
Hi all! Want to collect some ideas about the problem I have in Kotlin+Jackson space. I wanted to implement something like this:
Copy code
interface HttpResponseBody {
	val asString: String
	
	inline fun <reified T : Any> asInstanceOf(format: BodyFormat): T =
        when (format) {
            BodyFormat.JSON -> jacksonObjectMapper().readValue(asString)
        }
}
so I can utilize the jackson-kotlin support of reified type parameters to not pass class instance to the deserialization method and be able to use it like this
Copy code
response.body.asInstanceOf<User>(BodyFormat.JSON)
But
reified
only works in
inline
functions and I can't inline the function in interface. I was looking for not ugly way to workaround that and have similar implementation in place. So far I found two ways of doing this: 1. Convert
HttpResponseBody
to abstract class, so
inline
and
reified
are working. 2. Convert
asInstanceOf
method to the extension method of the
HttpResponseBody
interface. Both are working, but doesn't fit nicely with my other codebase (which I probably need to refactor), but I wanted to ask may be I am missing some other solutions?
m

mitch

06/28/2022, 9:50 PM
Hey @Alex Stelmachonak I'm curious of what others do as well but what I usually do is to define a non-inline function in the interface, and then declare an inline extension function on the interface. Something like this:
Copy code
interface HttpResponseBody {
  fun <T> instanceOf(bodyFormat: BodyFormat, clazz: Class<T>): T
}

inline fun <reified T> HttpResponseBody.instanceOf(bodyFormat: BodyFormat) = instanceOf(bodyFormat, T::class.java)
Oh you had tried this already in your second approach.
a

Alex Stelmachonak

06/28/2022, 9:57 PM
Thanks! The issue here is that I can't just call method from interface from the extension function - jackson kotlin method
readValue
requires generic type to be
reified
, which is not possible. If I just do
T::class.java
it kind of works, but looses the benefits of Kotlin classes additional runtime data. I.e. I can't just use data class without extra
@JsonProperty
annotations.
I will put this aside for some time and will try to fix it in few days - want to have a fresh look at this
d

DALDEI

07/02/2022, 8:26 AM
use the same type function that jackson-kotlin uses, not T::class.java use instanceOf( bodyFormat , jacksonTypeRef<T>() )
10 Views