• Java 中的 void 和 Kotlin 的 Unit


    1 Java 中的 void 和 Kotlin 中的 Unit

    在 Java 中,如果定义的函数没有返回值,就需要用 void 来修饰,即 void 不可以省略。这也在 Java 中不能说函数调用皆是表达式的原因,因为有些方法不具有返回值和类型信息,就不能算作是表达式。

    Java 在语言层设计一个 Void 类。java.lang.Void 类类似于 java.lang.Integer,Integer 是为了对基本类型 int 的实例进行装箱操作。Void 的设计则是为了对应 void。由于 void 表示没有返回值,所以,Void 并不能具有实例,它继承自 Object。

    在 Kotlin 中,函数在所有的情况下都有返回值类型,所以 Kotlin 引入了 Unit 来代替 Java 中的 void 关键字。

    Unit 和 int 一样,都是一种类型,然而,Unit 不代表任何信息。那么,Kotlin 为什么要引入 Unit 呢?很大一个原因是函数式编程。

    在 Kotlin 中,对象或者函数都有类型,如果方法的返回类型是 Unit 时,可以省略。

    对比:

    • Java 中的 void 表示什么都不返回,Kotlin 中的 Unit 是一个真实的数据类型;
    • Java 中的 void 是一个关键字,Kotlin 中的 Unit 是一个类;

    2 Any 和 Any? : 根类型

    和 Object 作为 Java 类层级结构的根差不多,Any 类型是 Kotlin 所有非空类型的超类型(非空类型的根)。

    但是在 Java 中,Object 只是所有引用类型的超类型(引用类型的根),而基本数据类型并不是类层级结构的一部分。这意味着当我们需要 Object 的时候,不得不使用像 java.lang.Integer 这样的包装类型来表示基本数据类型的值。

    而在 Kotlin 中,Any 是所有类型的超类型(所有类型的根),包括像 Int 这样的基本数据类型。

    和 Java 一样,把基本数据类型的值赋给 Any 类型的变量时会自动装箱:

    val answer: Any = 42 // Any 是引用类型,所以值 42 会被装箱
    
    • 1

    注意 Any 是非空类型,所以 Any 类型的变量不可以持有 null 值。在 Kotlin 中如果我们需要可以持有任何可能值的变量,包括 null 在内,必须使用 Any? 类型。

    在底层,Any 类型对应 java.lang.Object。Kotlin 把 Java 方法参数和返回类型中用到的 Object 类型看作 Any。当 Kotlin 函数使用 Any 时,它会被编译成 Java 字节码中的 Object。

    所有的 Kotlin 类中都包含:toString、equals 和 hashCode。这些方法都继承自 Any。Any 并不能使用其他 java.lang.Object 的方法(比如 wait 和 notify),但是可以通过手动把值转换成 java.lang.Object 来调用这些方法。

    3 Nothing 类型:这个函数永不返回

    对于某些 Kotlin 函数来说,“返回类型”的概念没有任何意义,因为它们不会成功地结束。 例如,许多测试库都有一个叫做 fail 的函数,它通过抛出带有特定消息的一场来让当前测试失败。一个包含无限循环的函数也永远不会成功地结束。

    当调用这样的函数代码时,知道函数永远不会正常终止是很有帮助的。Kotlin 使用一种特殊的返回类型 Nothing 来表示:

    fun main() {
        fail("Error occurred")
    }
    
    fun fail(message: String): Nothing {
        throw java.lang.IllegalStateException(message)
    }
    
    // Exception in thread "main" java.lang.IllegalStateException: Error occurred
    // 	at com.ixuea.test.TestKt.fail(Test.kt:158)
    // 	at com.ixuea.test.TestKt.main(Test.kt:152)
    // 	at com.ixuea.test.TestKt.main(Test.kt)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    Nothing 类型没有任何值,只有被当作函数返回值使用,或者被当作泛型函数返回值的类型参数使用才会有意义。在其他所有情况下,声明一个不能存储任何值的变量没有任何意义。

    Nothing 是没有任何实例的类型,Nothing 类型的表达式不会产生任何值。需要注意的是,任何返回值为 Nothing 的表达式之后的语句都是无法执行的。这里有点像 return 或者 break 的作用。在 Kotlin 中 return、throw 等,返回值都是 Nothing。

    注意,返回 Nothing 的函数可以放在 Elvis 运算符的右边来做先决条件检查:

    val address = company.address ?: fail("No address")
    println(address.city)
    
    • 1
    • 2

    上面这个例子展示了在类型系统中拥有 Nothing 为什么极其有用。编译器知道这种返回类型的函数从不正常终止,然后在分析调用这个函数的代码时利用这个信息。在上面的例子中,编译器会把 address 的类型推断成非空,因为它为 null 时的分支处理会始终抛出异常。

  • 相关阅读:
    快速入门python基础语法二(附加实现人生重开模拟器小案例)
    Redis(10)----AOF持久化
    java毕业设计城镇保障性住房管理系统mybatis+源码+调试部署+系统+数据库+lw
    GLTF纹理贴图工具让模型更逼真
    蜻蜓c影视追剧系统-多个小程序添加说明
    法律战爆发:“币安退出俄罗斯引发冲击波“
    很强,我终于找到绘制E-R图的正确姿势
    Postman如何导出接口的几种方法?
    SQL注入之 无列名注入 原理详解
    【微服务】SpringCloud-Nacos注册中心
  • 原文地址:https://blog.csdn.net/xingyu19911016/article/details/136836878