4.7 kotlin.Nothing类型

Kotlin中没有类似Java和C中的函数没有返回值的标记void,但是拥有一个对应Nothing。在Java中,返回void的方法,其返回值void是无法被访问到的:

  1. public class VoidDemo {
  2. public void voidDemo() {
  3. System.out.println("Hello,Void");
  4. }
  5. }

测试代码:

  1. @org.junit.runner.RunWith(org.junit.runners.JUnit4.class)
  2. public class VoidDemoTest {
  3. @org.junit.Test
  4. public void testVoid() {
  5. VoidDemo voidDemo = new VoidDemo();
  6. void v = voidDemo.voidDemo(); // 没有void变量类型,无法访问到void返回值
  7. System.out.println(voidDemo.voidDemo()); // error: 'void' type not allowed here
  8. }
  9. }

在Java中,void不能是变量的类型。也不能被当做值打印输出。但是,在Java中有个包装类Voidvoid 的自动装箱类型。如果你想让一个方法返回类型 永远是 null 的话, 可以把返回类型置为这个大写的V的Void类型。

代码示例:

  1. public Void voidDemo() {
  2. System.out.println("Hello,Void");
  3. return null;
  4. }

测试代码:

  1. @org.junit.runner.RunWith(org.junit.runners.JUnit4.class)
  2. public class VoidDemoTest {
  3. @org.junit.Test
  4. public void testVoid() {
  5. VoidDemo voidDemo = new VoidDemo();
  6. Void v = voidDemo.voidDemo(); // Hello,Void
  7. System.out.println(v); // null
  8. }
  9. }

这个Void就是Kotlin中的Nothing?。它的唯一可被访问到的返回值也是null

在Kotlin类型层次结构的最底层就是类型Nothing

Kotlin极简教程

正如它的名字Nothing所暗示的,Nothing是没有实例的类型。

代码示例:

  1. >>> Nothing() is Any
  2. error: cannot access '<init>': it is private in 'Nothing'
  3. Nothing() is Any
  4. ^

注意:Unit与Nothing之间的区别: Unit类型表达式计算结果的返回类型是Unit。Nothing类型的表达式计算结果是永远不会返回的(跟Java中的void相同)。

例如,throw关键字中断的表达式的计算,并抛出堆栈的功能。所以,一个throw Exception 的代码就是返回Nothing的表达式。代码示例:

  1. fun formatCell(value: Double): String =
  2. if (value.isNaN())
  3. throw IllegalArgumentException("$value is not a number") // Nothing
  4. else
  5. value.toString()

再例如, Kotlin的标准库里面的exitProcess函数:

  1. @file:kotlin.jvm.JvmName("ProcessKt")
  2. @file:kotlin.jvm.JvmVersion
  3. package kotlin.system
  4. /**
  5. * Terminates the currently running Java Virtual Machine. The
  6. * argument serves as a status code; by convention, a nonzero status
  7. * code indicates abnormal termination.
  8. *
  9. * This method never returns normally.
  10. */
  11. @kotlin.internal.InlineOnly
  12. public inline fun exitProcess(status: Int): Nothing {
  13. System.exit(status)
  14. throw RuntimeException("System.exit returned normally, while it was supposed to halt JVM.")
  15. }

Nothing?可以只包含一个值:null。代码示例:

  1. >>> var nul:Nothing?=null
  2. >>> nul = 1
  3. error: the integer literal does not conform to the expected type Nothing?
  4. nul = 1
  5. ^
  6. >>> nul = true
  7. error: the boolean literal does not conform to the expected type Nothing?
  8. nul = true
  9. ^
  10. >>> nul = null
  11. >>> nul
  12. null

从上面的代码示例,我们可以看出:Nothing?它唯一允许的值是null,被用作任何可空类型的空引用。

Kotlin极简教程

综上所述,我们可以看出Kotlin有一个简单而一致的类型系统。Any?是整个类型体系的顶部,Nothing是底部。如下图所示:

Kotlin极简教程