¿Qué estoy haciendo mal aquí?
fun main(args: Array<String> = arrayOf("abc")) { val a = args[0] }compila bien pero:
Excepción en el hilo "principal" java.lang.ArrayIndexOutOfBoundsException: 0
Quiero que sea opcional tener un argumento y proporcionar un valor predeterminado si no se especificó ninguno
Esto probablemente no funcione debido a cómo funciona la plataforma Java subyacente y cómo Kotlin traduce los argumentos predeterminados a algo que la JVM pueda entender. Se podría decir que es un error en Kotlin...
La máquina virtual Java busca un método con la siguiente firma para ejecutar su programa (esto es Java):
public static void main(String[] args)Tenga en cuenta que los valores de argumento predeterminados no existen en Java, por lo que si declara un método con valores predeterminados en Kotlin, el compilador de Kotlin genera varios métodos en el código de bytes de Java que se verá así cuando se convierta a 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" }); } Cuando ejecute el programa, la JVM aún buscará el método con el argumento String[] args . Ignorará el método sin argumentos, que se generó para el método main de Kotlin con argumentos predeterminados.
Por lo tanto, siempre llamará a la versión String[] args , incluso si no hay argumentos en la línea de comando, lo que genera el error que obtiene.
Solución alternativa: no utilice valores predeterminados para el método main ; compruebe si se dieron argumentos dentro del método:
fun main(args: Array<String>) { val realArgs = if (args.size > 0) args else arrayOf("abc") // work with realArgs }Creo que es una cuestión de firma la búsqueda de métodos main de JVM: un método main debe tener un parámetro de tipo String[] , y este parámetro recibe valores de CLI; si la CLI no proporciona ningún parámetro, el método main recibe un new String[0] , lo que provoca el error que está experimentando.
Creo que puedes resolver el problema cambiando ligeramente el enfoque:
fun main(args: Array<String>) { println(args) val a = args.getOrElse(0) {"abc"} println(a) } debería funcionar para su escenario: si no hay ningún parámetro con el índice 0 a obtiene el valor predeterminado que pasó (como lambda) a getOrElse .