Reputation: 173
I have the following Kotlin code:
fun handleResult(clazz: Any){
val store = App.getBoxStore();
if(clazz is List<*> && clazz.size > 0){
val items: List<*> = clazz;
val item = items.get(0);
val box = store.boxFor(item!!::class.java)
box.put(items)
}
}
It takes a object, checks if it is a collection and if it is, takes a item to check the class of the collection items, create a Box from a library called ObjectBox which is an database, and them put the list of items in the database.
However, i get the following error in the Box.put statment:
Error:(45, 17) None of the following functions can be called with the
arguments supplied:
public open fun put(@Nullable vararg p0: Nothing!): Unit defined in
io.objectbox.Box
public open fun put(@Nullable p0: (Nothing..Collection<Nothing!>?)):
Unit defined in io.objectbox.Box
public open fun put(p0: Nothing!): Long defined in io.objectbox.Box
The signature of the method I want to use is:
public void put(@Nullable Collection<T> entities)
It recivies a Collection of a generic type, as a list is a collection, it should work.
I've also explicitly casted it to a List, but it still says the same thing.
Thanks!
Upvotes: 1
Views: 469
Reputation: 38
The problem is that the generic Collection declaration needs an actual type. However, you're using List<*> which does not have a specified type and the compiler is assuming the generic type associated with the Box is "Nothing".
There are a couple of ways you can fix this.
If you know a specific set of types for which this will be used ahead of time, you can use a when statement to do a proper smart cast of the List type and then you'll be able to create a correct instance of Box call the put() method without an issue.
if(clazz is List<*> && clazz.size > 0){
val items = clazz
val item = items.get(0)
when (item) {
is Int -> {
val box = store.boxFor(Int::class.java)
box.put(items.filterIsInstance<Int>())
}
is ...
}
}
Use reflection to get the put() method from Box and then make the call on it. This will bypass the semantic checks of the compiler, but it's a bit more dubious and could run into issues later.
if(clazz is List<*> && clazz.size > 0){
val items = clazz
val item = items.get(0)
val box = store.boxFor(Int::class.java)
val putMethod = box::class.java.getDeclaredMethod("put", item!!::class.java)
putMethod.invoke(box, items)
}
Upvotes: 1