Hi all, following my question here <https://kotlin...
# serialization
g
Hi all, following my question here https://kotlinlang.slack.com/archives/C7A1U5PTM/p1604077940258100 - the only way to know at run time if an Any object is serializable and get serializer would be:
Copy code
fun <T : Any> getSerializer(obj: T) : KSerializer<T>? {
    val companionField = obj::class.java.declaredFields.find {
        it.name == "Companion" && isStatic(it.modifiers)
    } ?: return null

    val companion = companionField.get(obj)
    val serializerMethod = try {
        companion::class.java.getMethod("serializer")
    } catch (e: NoSuchMethodException) {
        return null
    }

    if (serializerMethod.returnType.name !=  KSerializer::class.qualifiedName) {
        return null
    }

    @Suppress("UNCHECKED_CAST")
    return serializerMethod.invoke(companion) as KSerializer<T>
}
Is it the right way? It's seem a bit cumbersome to me. Why not to add an interface?
t
Better use kotlinx.serialization.SerializersKt#serializer(java.lang.reflect.Type) or SerializersModule.serializer(type: Type)
g
Thx, I was not aware of that and ended up with
Copy code
fun <T : Any> getKSerializerOrNull(klass: Class<out T>) = 
    try {
        @Suppress("UNCHECKED_CAST")
        serializer(klass.kotlin.createType()) as KSerializer<T>
    } catch (e: Exception) { 
        null 
    }
Hi, I come back, as there is actually issues with the proposed solution:
klass.kotlin.createType()
is not reliable in this context, for example if klass is a non-empty List<User>, it will fail.
So it's still unclear to me how to deal with this situation (klass is a user provided java class, I do not have control on it)
After digging, I can use
Copy code
@OptIn(ExperimentalStdlibApi::class)
inline fun <reified T : Any> getKSerializerOrNull(klass: Class<out T>) = try {
    @Suppress("UNCHECKED_CAST")
    serializer(typeOf<T>()) as KSerializer<T>
} catch (e: SerializationException) {
    null
}
but at the cost of using an experimental api
Ok - actually this above does not work, as if klass comes from a deserialization, I've lost the type at runtime 😅 - so I guess I can only use the initial complex solution