Actual type of class in runtime in Kotlin for Json handler wrapper

Viewed 163

I'm trying to write a wrapper class (a port and an adapter if you will) for a JsonHandler so that I can easily swap out my dependency if needed.

Here is what I'd like to have for my port:

interface JsonHandler {
    fun <Type : Any> serialize(instance: Type): String

    fun <Type : Any> deserialize(json: String, type: Class<Type>): Type
}

The issue that I'm facing now is that I want to use Moshi for this, so this is how I was trying to write my adapter:

class MoshiJsonHandler(private val moshi: Moshi) : JsonHandler {
    override fun <T : Any> serialize(instance: T): String {
        return moshi.adapter(instance::class.java).toJson(instance)
    }
    //deserialize ommited for brevity

However that gives me an error:

Type mismatch: inferred type is T#1 (type parameter of MoshiJsonHandler.serialize) but Nothing? was expected. Projected type JsonAdapter<out T#1!>! restricts use of public final fun toJson(p0: T#2 (type parameter of com.squareup.moshi.JsonAdapter)?): String! defined in com.squareup.moshi.JsonAdapter

I'm not great with generics, but I vaguely understand that asking for instance::class.java where instance is of type T is not something that Kotlin/Java likes. So I ended up with this changed signature and implementation:

class MoshiJsonHandler(private val moshi: Moshi) : JsonHandler {
    override fun <T : Any> serialize(instance: T, type: Class<T>): String {
        return moshi.adapter(type).toJson(instance)
    }
}

That's far from ideal though, because if I switch to gson then I'll have this redundant type argument in my serialize() method. Is there a way to fix my first attempt and not have to provide an extra Class<T> parameter?

0 Answers
Related