• Java 及 Kotlin 中的可变参数 vararg


    本文地址


    目录

    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

  • 相关阅读:
    AWR
    geth入门命令和miner.start返回null的问题
    以太坊geth区块链私链建立
    Ubuntu无法找到add-apt-repository问题的解决方法
    Truffle测试框架
    TypeError: Data location must be "memory" for return parameter in function, but none was given.
    详解 Solidity 事件Event
    以太坊 Geth 环境搭建(Ubuntu)
    智能合约调试指南
    Truffle Smart Contract Error: Invalid number of parameter
  • 原文地址:https://www.cnblogs.com/baiqiantao/p/16216523.html
Copyright © 2020-2023  润新知