Reputation: 1622
I am getting the following error Unable to invoke no-args constructor for class Entry. Registering an InstanceCreator with Gson for this type may fix this problem.
My code extends an Entry class.
abstract class Data : ArrayList<Entry>() {
//code removed for simplicity
abstract class Entry(str: String) {
open var name: String = str
}
}
class Category: Data() {
class CategoryItem(
override var name: String
) : Entry(name)
}
I have a handler class to handle the transaction.
class JsonHelper(private var type: KClass<Category>) {
private val json = Gson()
private var contents: String? = null
private var data: Any? = null
fun convert(string: String): Any? {
data = json.fromJson(string, type.java)
return data
}
}
I call
json = JsonHelper(Category::class)
json.convert(file.read())
//file.read() comes from a file as a string, this works as intended
previously I had it setup where Entry was just an empty class and I added the name field while debugging, but it had no effect. I have searched on stackoverflow and haven't found anything that would help, except that you shouldn't use suspend to call it, which you can see im not.
I have also tried using a TypeToken
which I would pass into json.fromJson(string, type)
at runtime, this also didn't help.
private var type = object: TypeToken<Category>(){}.type
Any Ideas? I would like gson to return a Category type class to me.
Upvotes: 0
Views: 2498
Reputation: 170815
Well, Category
extends ArrayList<Entry>
, so GSON needs to know how to instantiate an Entry
and it can't because it's abstract.
If the intention is that a Category
should only contain CategoryItem
, not arbitrary Entry
, it should be
abstract class Data<T : Entry> : ArrayList<T>() {
abstract class Entry(str: String) {
open var name: String = str
}
}
class Category: Data<CategoryItem>() {
class CategoryItem(
override var name: String = ""
) : Entry(name)
}
Extending ArrayList
instead of having a field of that type is also not usually a good idea.
Upvotes: 1