从kotlin调用java varargs方法

时间:2016-04-14 14:26:53

标签: kotlin

我有一个java函数:

public static void initialize(@NonNull Activity activity, Settings... settings) {}

我想从kotlin那里打电话:

fun initialize(activity: Activity, vararg settings: settings) = JavaClass.initialize(activity, settings)

但它没有编译,告诉我类型不匹配,Settings是必需的,但参数是kotlin.Array<out Settings>

我看到它正试图将它与signture相匹配

public static void initialize(@NonNull Activity activity, Settings settings) {}

但我想用

public static void initialize(@NonNull Activity activity, Settings[] settings) {}

2 个答案:

答案 0 :(得分:15)

您应该使用以下语法:

Select nvcName from bts_application

https://kotlinlang.org/docs/reference/java-interop.html#java-varargs

答案 1 :(得分:2)

Michael's answer是正确的,尽管我想提出一些其他意见。

无法将Kotlin vararg参数传递给需要另一个vararg的Java(或Kotlin)函数的原因是因为编译器将vararg解析为Array

因此,就好像您声明了以下函数一样(从函数内部作用域的角度来看 ):

fun initialize(activity: Activity, settings: Array<Settings>) = //...

这就是为什么我们需要使用传播*运算符并不直观。据我所知,这种设计选择有两个好处:

  1. 除了用于填充变量自变量之外,扩展运算符还可以用于在各个自变量和扩展数组之间进行混合匹配。这意味着Kotlin为我们提供了一种方便的方法,可以向vararg列表中添加其他参数。

    在Java中,以下代码无法编译:

    Settings[] settings = //...
    Setting myAdditionalSetting = new Setting();
    JavaClass.initialize(activity, settings, myAdditionalSetting); //Compiler Error 
    

    但是,在Kotlin中,我们可以这样做:

    JavaClass.initialize(activity, *settings, myAdditionalSetting)
    
  2. 第二个好处是提高了安全性。扩展运算符编译为对Arrays.copyOf()的调用,以保证扩展值的不变性。 i 这样可确保所调用的函数不会破坏原始数组。

i:虽然实际的类 references 是不可变的,但它们引用的对象可能仍然是可变的。