From Punched Cards to Prompts
AndroidIntroduction When computer programming was young, code was punched into cards. That is, holes were punched into a piece of cardboard in a format...
This article explores the usefulness of Kotlin’s Nothing
type in generics. We look at its relationship to Java. To take a concrete example, let’s look at a linked list.
A LinkedList wraps some type T
. The linked list can either be
Node<T>
with two properties: a payload
of T
and a next
of type LinkedList<T>
; orEmptyList
.sealed class
enforces that the LinkedList
is either type 1 or type 2.We can readily code up the sealed class
and the Node<T>
as follows:
sealed class LinkedList<out T> {
data class Node<T>(val payload: T, var next: LinkedList<T> ) : LinkedList<T>()
}
Coding up the empty list is a bit more challenging. All empty lists are the same. So, an empty list is an object
. EmptyList
must also be a subclass of LinkedList<T>
. We might try to write
sealed class LinkedList<out T> {
data class Node<T>(val payload: T, var next: LinkedList<T> ) : LinkedList<T>()
object EmptyList<T> : LinkedList<T>() // won't compile
}
Kotlin objects cannot have type parameters. The above code will not compile. Instead, we might try to remove the EmptyList’s type parameter.
sealed class LinkedList<out T> {
data class Node<T>(val payload: T, var next: LinkedList<T> ) : LinkedList<T>()
object EmptyList : LinkedList<T>() // won't compile
}
The code still does not compile. The reference to T
in line 5 is unresolved. We must stipulate a concrete type for T
.
T
is the type of the payload wrapped by a node. See Fig. 1 above. By contrast, an empty list wraps no payload. So, the proper coding is
sealed class LinkedList<out T> {
data class Node<T>(val payload: T, var next: LinkedList<T> = EmptyList) : LinkedList<T>()
object EmptyList : LinkedList<Nothing>()
}
val nonEmptyList = LinkedList.Node(payload = "A", next = LinkedList.Node(payload = "B"))
What is the Kotlin Nothing
type? From Android Studio, select Tools -> Kotlin -> Kotlin REPL. In the REPL window, enter and run the command println(Nothing::class.java)
. The result is
println(Nothing::class.java)
class java.lang.Void
Kotlin’s Nothing
type is backed by Java’s Void
type. Kotlin’s Nothing
type indicates the absence of type.
As a side point, why can’t we define a Kotlin function to return Nothing
? For example, this code will not compile:
fun getNothing() = Nothing() // won't compile
Kotlin does not allow Nothing to be instantiated. The constructor for Nothing
is private. Compare the above code to the Java equivalent:
public class GetVoidExample {
public Void getVoid() {
return new Void(); // won't compile
}
}
Java’s Void
class has a private constructor. Void
cannot be instantiated. We cannot return a Void
. So, it seems reasonable that we cannot return a Nothing
in Kotlin.
We have shown that Kotlin’s Nothing
type is backed by Java’s Void
type. Kotlin’s Nothing
type is used to indicate that a generic type wraps no type. The type is absent.
Allan Caine is a Big Nerd Ranch Alumni. If you would like to connect with Allan, visit his LinkedIn at https://www.linkedin.com/in/adcaine/.
Introduction When computer programming was young, code was punched into cards. That is, holes were punched into a piece of cardboard in a format...
Jetpack Compose is a declarative framework for building native Android UI recommended by Google. To simplify and accelerate UI development, the framework turns the...
Big Nerd Ranch is chock-full of incredibly talented people. Today, we’re starting a series, Tell Our BNR Story, where folks within our industry share...