kotlin_基础_可变参数

22 篇文章 0 订阅
本文探讨了Kotlin和Java中的可变参数差异,指出两者本质上都是数组。在Kotlin中,可变参数通过`vararg`关键字实现,其传参时需注意数组与可变参数之间的转换。当尝试将数组类型传递给可变参数时,需使用`*`操作符。通过反编译,可以看到`*`操作符实际执行了数组复制。总结来说,Kotlin的可变参数在传参上有特定规则,与Java相比有其独特之处。
摘要由CSDN通过智能技术生成

对比 Java 中的可变参数

先看下 Java 的可变参数,用我们最熟悉的 main 函数

	public static void main(String... args) {
    }

很多人可能都觉得不对啊,参数应该是数组啊

    public static void main(String[] args) {
    }

其实上面两种写法是一样的,从 Java5 开始引入了可变参数(varargs)

对应的 Kotlin 的代码,也是两种方式,参数为数组:

    fun main(args: Array<String>) {
    }

参数为可变参数:

    fun main(vararg args: String) {
    }

可变参数的本质

和 Java 一样,可变参数的本质就是数组,我们来测试一下:

    fun main() {
        foo("1", "2", "3")
    }
    
    fun foo(vararg args: String) {
        println(args::class)
        println(args.contentToString())
        for (i in args.indices) {
            println(args[i])
        }
    }

打印:

    class kotlin.Array
    val kotlin.reflect.KClass<T>.java: java.lang.Class<T>
    [1, 2, 3]
    1
    2
    3

我们可以清晰的看到 args 的类型为数组类型,并且可以直接调用数组的方法。

如果你的第一行打印结果是:
class [Ljava.lang.String; (Kotlin reflection is not available)
需要在 build.gradle 中添加依赖:
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"

准确的说 args 的类型是 Array<out String> 类型:

    fun main() {
        foo("1", "2", "3")
    }
    
    fun foo(vararg args: String) {
        bar(args)
    }
    
    fun bar(args: Array<out String>) {
        println(args.contentToString())
    }

可变参数的传参

我们再来改造一下 bar 函数的参数类型,看下可变参数的传参:

    fun main() {
        foo("1", "2", "3")
    }
    
    fun foo(vararg args: String) {
        bar(args)
    }
    
    fun bar(vararg args: String) {
        println(args.contentToString())
    }

编译器提示类型不匹配,需要一个 String 类型的参数,而传入了数组类型。

在这里插入图片描述

传参报错

在 Java 中可变参数是可以直接传递,并且可以和数组相互转换传递:

    public static void main(String[] args) {
        foo("1", "2", "3");
    }
    
    private static void foo(String... args) {
        bar1(args);
        bar2(args);
    }
    
    private static void bar1(String... args) {
        System.out.println(Arrays.toString(args));
    }
    
    private static void bar2(String[] args) {
        bar1(args);
    }

在 Kotlin 中如果想将数组类型传入到可变参数,就需要使用一个特定的符号 *

    fun main() {
        foo("1", "2", "3")
    }
    
    fun foo(vararg args: String) {
        bar1(*args)
        bar2(args)
    }
    
    fun bar1(vararg args: String) {
        println(args.contentToString())
    }
    
    fun bar2(args: Array<out String>) {
        bar1(*args)
    }

总结

我对 Kotlin 中d可变参数的理解是:

  1. 可变参数会在函数体中,自动转变为数组类型
  2. 数组类型不能作为参数,直接传递给可变参数
  3. 在数组类型前面添加 * ,可以传递给可变参数

最后,我们可以反编译看下 Kotlin 中的 foo 函数,看看 * 到底做了什么:

    public static final void foo(@NotNull String... args) {
        bar1((String[]) Arrays.copyOf(args, args.length));
        bar2(args);
    }

就是一个复制数组的操作,相比 Kotlin 还是 Java 做的更便捷,可以在数组和可变参数之间直接自由转换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值