Kotlin中的Any、Unit、Nothing

发布时间 2023-06-01 12:32:08作者: jqc

Any

Kotlin中的Any即相当于Java中的Object类,是一切其他非空类型的父类型,Any?则表示一切可空类型的父类型。

Any拥有三个方法:

  • equals()
  • hashCode()
  • toString()

事实上Any在编译成字节码后正是会转成java.lang.Object类。

Unit

Kotlin中的Unit即相当于Java中的void关键字,用于表示返回空结果的函数。

fun test() : Unit {
 	println("test return void")
	return Unit
}

其中Unit可以省略,即等同于

fun test() {
 	println("test return void")
}

转换成java代码:

void test() {
	System.out.println("test return void")
}

Unit 在Kotlin中实际是一个全局的static对象,Unit的源码如下:

public object Unit {
    override fun toString() = "kotlin.Unit"
}

Nonthing

Kotlin中的Nothing是一个很特别的存在,它有点类似于Java中的java.lang.Void类。

Kotlin中的Nothing的源码如下:

public class Nothing private constructor()

Kotlin中的Nothing类的主构造函数是private的,使得Nothing类不可能被实例化。

Java中的Void类的源码如下:

public final class Void {
    /*
     * The Void class cannot be instantiated.
     */
    private Void() {}
}

同样的,Java中Void类也是无法被实例化的。

Kotlin中Nothing通常用在抛出异常的场景,表示一段代码不应该执行到,例如:

fun fail(message: String): Nothing {
    throw IllegalArgumentException(message)
}

上述代码中fail函数返回的类型是Nothing,表示的含义即fail函数不会有返回值。事实上Kotlin中throw表达式是有返回的类型的,返回的类型就是Nothing类型。

val name = person.name ?: fail("Name required")

上述代码中的name变量在非空的时候类型就是String,而在走到失败分支的时候其类型就是Nothing,上述代码还可以这样写:

val name: String = person.name ?: fail("Name required")

这就是Nothing的另一个特性,Nothing类可以作为所有类的子类型,所以上述代码中Nothing类型可以是String类的子类型。

我们可以用Unit来作为对比:

val name: String = person.name ?: Unit			//编译器会报错Type mismatch

那么Nothing?表示什么呢?Nothing?表示可空的Nothing类型,Kotlin中的null就是Nothing?类型的唯一值,也就是说所有可空类型的对象的初始值就是null