目录
目录
Java 及 Kotlin 中的可变参数 vararg
Java 中可变参数的规则
- 可变参数只能出现在参数列表的最后
- 用
...
代表可变参数,...
位于变量类型和变量名之间 - 在方法体中以
数组
的形式访问可变参数
Kotlin 中的规则类似
可变参数的本质是数组
Java 中对应数组 T[]
public static void hello(String[] array, String... args) {
Class<?> stringArrayClass = Array.newInstance(String.class, 0).getClass(); // 获取数组的 Class
System.out.println(array.getClass() == args.getClass()); // true
System.out.println(array.getClass() == stringArrayClass); // true
System.out.println(args.getClass().getName()); // [Ljava.lang.String;
}
上面代码中的 stringArrayClass 代表的就是
String 数组的 Class
对象,参考
Kotlin 中可能对应 Array
fun hello(array: Array<String>, vararg args: String) {
val stringArrayClass: Class<*> = java.lang.reflect.Array.newInstance(String::class.java, 0).javaClass
println(array.javaClass == args.javaClass) // true
println(array.javaClass == stringArrayClass) // true
println(args.javaClass.name) // [Ljava.lang.String;
}
或 IntArray 等衍生数组
fun hello(array: IntArray, vararg args: Int) {
val intPrimitiveType: Class<Int>? = Int::class.javaPrimitiveType
val intArrayClass: Class<*> = java.lang.reflect.Array.newInstance(intPrimitiveType, 0).javaClass
println(array.javaClass == args.javaClass) // true
println(array.javaClass == intArrayClass) // true
println(args.javaClass.name) // [I
}
可变参数的应用
可变参数的声明
public static void javaTest(String name, int... args) {
System.out.println(name + " -- " + args.length);
}
fun kotlinTest(name: String, vararg args: Int) = println("$name - ${args.size}")
可变参数是否可为空
- Java 中可变参数
可为空
,所以在调用前必须判空 - Kotlin 中可变参数
不可为空
,所以在调用前不需要判空- 如果判空了,IDE 会提示你:Condition 'args==null' is always 'false'
- 在 Java 中调用 Kotlin 的可变参数时,虽然传 null 可以编译通过,但运行时会直接崩溃
javaTest("bqt"); // bqt - 0
javaTest("bqt", null); // 编译通过,运行时崩溃
MainKt.kotlinTest("bqt", null); // 编译通过,运行时会直接崩溃
kotlinTest("bqt") // bqt - 0
kotlinTest("bqt", null) // 编译不通过,Null can not be a value of a non-null type Int
javaTest("bqt", null) // 编译不通过,Null can not be a value of a non-null type Int
可变参数的调用
在 Kotlin 中,如果想将数组
传入到可变参数,需要在引用前面加上 *
。
public static void javaTest(String name, int... args) {
MainKt.kotlinTest(name, 1, 2); // 这里的 MainKt 是自动生成的一个类,用于封装 Kotlin 中的顶层函数
MainKt.kotlinTest(name, args);
MainKt.kotlinTest(name, new int[]{1, 2, 3});
}
Java 中调用 Kotlin 中定义的顶层函数时,需要以
静态方法
的语法去调用,类名是 Kotlin文件名
+ 后缀Kt
。
fun kotlinTest(name: String, vararg args: Int) {
Test.javaTest(name, 1, 2, 3)
Test.javaTest(name, *args)
Test.javaTest(name, *IntArray(3)) // 这里的 3 代表的其实是 size
}
Kotlin 类型转换
fun main() {
intTest("IntArray", *intArrayOf(1, 2, 3)) // Remove redundant spread operator
intTest("Array<Int>", *arrayOf(1, 2, 3).toIntArray())
intTest("List<Int>", *listOf(1, 2, 3).toIntArray())
val stringArray = com.sun.xml.internal.fastinfoset.util.StringArray().also { it.add("1") }
stringTest("StringArray", *stringArray.array)
stringTest("Array<String>", *arrayOf("2")) // Remove redundant spread operator
stringTest("List<String>", *listOf("3").toTypedArray())
}
fun intTest(name: String, vararg args: Int) = println("$name - ${args.toList()}")
fun stringTest(name: String, vararg args: String) = println("$name - ${args.toList()}")
StringArray 并不是 Kotlin 中定义的类,而是一个 Java 类。继承自 ValueArray(继承自 Object)
StringArray.array 其实是调用了 public String[] getArray() 方法
2022-5-2