1. Introduction

In this tutorial, we’ll learn about Void type in Kotlin and essentially other ways to represent void or nothing in Kotlin.

2. Void vs void – in Java

To understand the use of Void in Kotlin, let’s first review what is a Void type in Java and how it is different from the Java primitive keyword void.

The Void class, as part of the java.lang package, acts as a reference to objects that wrap the Java primitive type void.** It can be considered analogous to other wrapper classes such as Integer — the wrapper for the primitive type int.

Now, Void is not amongst the other popular wrapper classes because there are not many uses cases where we need to return it instead of the primitive void. But, in applications such as generics, where we can not use primitives, we use the Void class instead.

3. Void in Kotlin

Kotlin is designed to be completely interoperable with Java and hence Java code can be used in Kotlin files.

Let’s try to use Java’s Void type as a return type in a Kotlin function:

fun returnTypeAsVoidAttempt1() : Void {
    println("Trying with Void return type")
}

But this function doesn’t compile and results in below error:

Error: Kotlin: A 'return' expression required in a function with a block body ('{...}')

This error makes sense and a similar function would have given a similar error in Java.

To fix this, we’ll try to add a return statement. But, since Void is a non-instantiable final class of Java, we can only return null from such functions:**

fun returnTypeAsVoidAttempt2(): Void {
    println("Trying with Void as return type")
    return null
}

This solution doesn’t work either and fails with the following error:

Error: Kotlin: Null can not be a value of a non-null type Void

The reason for the above message is that unlike Java, we cannot return null from non-null return types in Kotlin.

In Kotlin, we need to make the function return type nullable by using the ? operator:

fun returnTypeAsVoidSuccess(): Void? {
    println("Function can have Void as return type")
    return null
}

We finally have a solution that works, but as we’ll see next, there are better ways of achieving the same result.

4. Unit in Kotlin

Unit in Kotlin can be used as the return type of functions that do not return anything meaningful:

fun unitReturnTypeForNonMeaningfulReturns(): Unit {
    println("No meaningful return")
}

By default, Java void is mapped to Unit type in Kotlin. This means that any method that returns void in Java when called from Kotlin will return Unit for example the System.out.println() function*.*

@Test
fun givenJavaVoidFunction_thenMappedToKotlinUnit() {
    assertTrue(System.out.println() is Unit)
}

Also, Unit is the default return type and declaring it is optional, therefore, the below function is also valid:

fun unitReturnTypeIsImplicit() {
    println("Unit Return type is implicit")
}

5. Nothing in Kotlin

Nothing is a special type in Kotlin that is used to represent a value that never exists. If a function’s return type is Nothing then that function doesn’t return any value not even the default return type Unit.

For example, the function below always throws an exception:

fun alwaysThrowException(): Nothing {
    throw IllegalArgumentException()
}

As we can appreciate, the concept of the Nothing return type is quite different and there is no equivalent in Java. In the latter, a function will always default to void return type even though there may be cases like the above example when that function may never return anything.

The Nothing return type in Kotlin saves us from potential bugs and unwarranted code. When any function having Nothing as the return type is invoked, then the compiler will not execute beyond this function call and gives us the appropriate warning:

fun invokeANothingOnlyFunction() {
    alwaysThrowException() // Function that never returns
    var name="Tom" // Compiler warns that this is unreachable code
}

6. Conclusion

In this tutorial, we learned about void vs Void in Java and how to use them in Kotlin. We also learned about Unit and Nothing types and their applicability as return types for different scenarios.

As always, all the code used in this tutorial is available over on GitHub.


» 下一篇: 在Kotlin中构建DSL