Gilles Barbier
11/05/2020, 5:31 PMfun <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?Tomasz Krakowiak
11/06/2020, 6:03 AMGilles Barbier
11/06/2020, 9:07 AMfun <T : Any> getKSerializerOrNull(klass: Class<out T>) =
try {
@Suppress("UNCHECKED_CAST")
serializer(klass.kotlin.createType()) as KSerializer<T>
} catch (e: Exception) {
null
}
Gilles Barbier
11/09/2020, 10:35 AMklass.kotlin.createType()
is not reliable in this context, for example if klass is a non-empty List<User>, it will fail.Gilles Barbier
11/09/2020, 10:36 AMGilles Barbier
11/09/2020, 11:02 AM@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 apiGilles Barbier
11/10/2020, 10:55 PM