我在这里做什么错了?
fun main(args: Array<String> = arrayOf("abc")) {
val a = args[0]
}
编译正常,但是:
线程“ main”中的异常java.lang.ArrayIndexOutOfBoundsException:0
我想使其具有参数作为可选参数,并在未指定参数的情况下提供默认值
答案 0 :(得分:8)
由于底层Java平台的工作方式以及Kotlin如何将默认参数转换为JVM可以理解的内容,因此这可能行不通。您可以说这是Kotlin中的错误...
Java虚拟机正在寻找一种具有以下签名的方法来运行程序(这是Java):
public static void main(String[] args)
请注意,默认参数值在Java中不存在,因此,如果在Kotlin中声明具有默认值的方法,则Kotlin编译器会在Java字节码中生成多个方法,这些方法在转换为Java时将如下所示:
public static void main(String[] args) {
// the normal main method
}
// generated because you have a method with default values
public static void main() {
main(new String[]{ "abc" });
}
运行程序时,JVM仍将寻找带有String[] args
参数的方法。它将忽略不带参数的方法,该方法是为带有默认参数的Kotlin main
方法生成的。
因此,即使命令行上没有任何参数,也总是要调用String[] args
版本-导致出现错误。
解决方法:不要对main
方法使用默认值;检查参数是否在方法内部给出:
fun main(args: Array<String>) {
val realArgs = if (args.size > 0) args else arrayOf("abc")
// work with realArgs
}
答案 1 :(得分:3)
我认为这是JVM搜索main
方法的签名问题:main
方法应具有一个String[]
类型的参数,并且此参数从CLI接收值;如果CLI不提供任何参数,则main
方法将收到new String[0]
,这将导致您遇到错误。
我认为您可以通过稍微改变方法来解决问题:
fun main(args: Array<String>) {
println(args)
val a = args.getOrElse(0) {"abc"}
println(a)
}
适用于您的情况:如果没有索引为0
的参数,则a
获得您传递给getOrElse
的默认值(作为lambda)。