Understanding Kotlin’s Any, Unit, Nothing

Understanding Kotlin’s Any, Unit, Nothing

Kotlin offers unique types that can be quite different from what developers are used to in Java. In this blog, we will explore three such types: Any, Unit, and Nothing.

Any

//SOURCE CODE
package kotlin
/**
 * The root of the Kotlin class hierarchy. Every Kotlin class has [Any] as a superclass.
 */
public open class Any {
    public open operator fun equals(other: Any?): Boolean
    public open fun hashCode(): Int
    public open fun toString(): String
}
  • Root of the class hierarchy. Every Kotlin class inherits from Any.

  • Equivalent to Object in Java.

  • Provides three methods that we can override: equals(), hashCode(), and toString(). This is why when we override methods in any class, these three options are often presented by the IDE.

  • Non-nullable by Default. If we need a variable to be able to hold null, we can use Any?.

Example

fun printAny(value: Any?) {
    println(value.toString())
}

fun main() {
    printAny("Hello, World!")  // Prints: Hello, World!
    printAny(123)  // Prints: 123
}
//When decompiled, Any becomes Object in Java
public static final void printAny(@Nullable Object value) {
   String var1 = String.valueOf(value);
   System.out.println(var1);
}

Unit

//SOURCE CODE
package kotlin
/**
 * The type with only one value: the `Unit` object. This type corresponds to the `void` type in Java.
 */
public object Unit {
    override fun toString() = "kotlin.Unit"
}
  • Equivalent to void in Java but unlike void ,Unit is a real class with only one instance (singleton).

  • Represent a function that does not return any meaningful value.

  • If we do not specify a return type for a function, Kotlin uses Unit as the default return type.

Example

fun printMessage(message: String): Unit { //There is no need to explicitly write Unit
    println(message)
}

fun main() {
    printMessage("Hello, Unit!")  // Prints: Hello, Unit!
}
//When decompiled, Unit becomes void in Java
public static final void printMessage(@NotNull String message) {
   Intrinsics.checkNotNullParameter(message, "message");
   System.out.println(message);
}

Example: Functional Type

fun runBlock(block: ()->Unit) {
    block()
}

fun main() {
    runBlock { println("Here") } // Prints: Here
}

Here, () -> Unit is a function type and the Unit indicates that this function type does not return any meaningful value.

In function type mentioning the Unit is compulsory.

Nothing

//SOURCE CODE
package kotlin
/**
 * Nothing has no instances. You can use Nothing to represent "a value that never exists": for example,
 * if a function has the return type of Nothing, it means that it never returns (always throws an exception).
 */
public class Nothing private constructor()
  • Represents the absence of any value indicating that a function will never return normally.

  • Subtype of all well-formed Kotlin types, including user-defined ones.

  • Used for functions that never return, either because they throw an exception or enter an infinite loop.

  • We cannot create an instance of Nothing, nor can any class inherit from it.

  • Functions with a return type of Nothing doesn’t return any value not even the default return type Unit .

  • The Nothing return type in Kotlin saves us from potential bugs by making it clear that they do not return. 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 Unreachable code warning.

Example

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

fun main() {
    // This will throw an exception and never return normally
    fail("This is an error!")
    println("Hello") // Compiler gives warning "Unreachable code"
}
//When decompiled, Nothing becomes Void in Java
//Void is part of the java.lang package, acts as a reference to objects that wrap the Java primitive type void. It is uninstantiable.
@NotNull
public static final Void fail(@NotNull String message) {
   Intrinsics.checkNotNullParameter(message, "message");
   throw (Throwable)(new IllegalArgumentException(message));
}

Source Code: Github

Contact Me:

LinkedIn, Twitter

Happy Coding ✌️