智能演员没有按预期工作

时间:2017-11-08 20:00:07

标签: kotlin kotlin-interop

我有以下Kotlin代码:

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)
    }
}

它需要一个对象,检查它是否是一个集合,如果是,则需要一个项来检查集合项的类,从一个名为ObjectBox的库中创建一个Box,这是一个数据库,然后它们放入数据库中的项目。

但是,我在Box.put语句中收到以下错误:

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

我想要使用的方法的签名是:

 public void put(@Nullable Collection<T> entities)

它会重现一个泛型类型的集合,因为列表是一个集合,它应该可以工作。

我还明确地将它转换为List,但它仍然说同样的事情。

谢谢!

1 个答案:

答案 0 :(得分:1)

问题是泛型Collection声明需要一个实际类型。但是,您正在使用List&lt; *&gt;它没有指定的类型,并且编译器假定与Box关联的泛型类型是&#34; Nothing&#34;。

有几种方法可以解决这个问题。

  • 如果您知道将提前使用的特定类型的一组,您可以使用when语句对List类型进行适当的智能投射,然后您就可以创建一个正确的Box实例调用put()方法没有问题。

    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 ...
        }
    
    }
    
  • 使用反射从Box获取put()方法,然后对其进行调用。这将绕过编译器的语义检查,但它有点可疑,可能会在以后遇到问题。

    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)
    }