I've encountered a weird behavior using Gson deserializing within a function with reified
type. It only happens when interfaces
are involved in the type parameter.
Take the following code:
val toBeSerialized = listOf("1337")
with(Gson()) {
val ser = toJson(toBeSerialized)
val deser = fromJson<List<Serializable>>(ser)
}
Line number 4 makes use of a custom extension function Gson.fromJson(json: String): T
.
It fails if T
is defined as reified:
inline fun <reified T> Gson.fromJson(json: String): T = fromJson<T>(json, object : TypeToken<T>() {}.type)
And it works if it is defined as a normal type parameter:
fun <T> Gson.fromJson(json: String): T = fromJson<T>(json, object : TypeToken<T>() {}.type)
(Note that making T
reified makes no sense here, just want to understand its impact in the special use case)
The exception when using reified
looks as follows:
Exception in thread "main" java.lang.RuntimeException: Unable to invoke no-args constructor for ? extends java.io.Serializable. Registering an InstanceCreator with Gson for this type may fix this problem.
at com.google.gson.internal.ConstructorConstructor$14.construct(ConstructorConstructor.java:226)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:210)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
at com.google.gson.Gson.fromJson(Gson.java:888)
at com.google.gson.Gson.fromJson(Gson.java:853)
at com.google.gson.Gson.fromJson(Gson.java:802)
at SoTestsKt.main(SoTests.kt:25)
Caused by: java.lang.UnsupportedOperationException: Interface can't be instantiated! Interface name: java.io.Serializable
at com.google.gson.internal.UnsafeAllocator.assertInstantiable(UnsafeAllocator.java:117)
at com.google.gson.internal.UnsafeAllocator$1.newInstance(UnsafeAllocator.java:49)
at com.google.gson.internal.ConstructorConstructor$14.construct(ConstructorConstructor.java:223)
... 8 more