Kotlin has some new things: Unit
Any
and Nothing
, here is my understanding of these three brothers.
Unit
First, look at the definition of Unit
in Kotlin:
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" }
As you can see, first of all, Unit
itself is a singleton represented by object
, so it can be understood that Kotlin has a class that has only one singleton object called >Unit
. This type is similar to Void
in Java. Since in Kotlin, all methods/functions are expressions, expressions always have a value, so each method must have a return value. If there is no explicit specification with return
, then generally speaking, it will automatically add Unit
for us, which is equivalent to this:
fun returnUnit():Unit{ return unit }
The return value type is Unit, and the singleton object Unit of Unit is actually returned.
Any
First look at how Kotlin is defined:
package kotlin /** * The root of the Kotlin class hierarchy. Every Kotlin class has [Any] as a superclass. */ public open class Any { /** * Indicates whether some other object is "equal to" this one. Implementations must fulfill the following *requirements: * * * Reflexive: for any non-null value `x`, `x.equals(x)` should return true. * * Symmetric: for any non-null values `x` and `y`, `x.equals(y)` should return true if and only if `y.equals(x)` returns true. * * Transitive: for any non-null values `x`, `y`, and `z`, if `x.equals(y)` returns true and `y.equals(z)` returns true, then `x. equals(z)` should return true. * * Consistent: for any non-null values `x` and `y`, multiple invocations of `x.equals(y)` consistently return true or consistently return false, provided no information used in `equals` comparisons on the objects is modified. * * Never equal to null: for any non-null value `x`, `x.equals(null)` should return false. * * Read more about [equality](https://kotlinlang.org/docs/reference/equality.html) in Kotlin. */ public open operator fun equals(other: Any?): Boolean /** * Returns a hash code value for the object. The general contract of `hashCode` is: * * * Whenever it is invoked on the same object more than once, the `hashCode` method must consistently return the same integer, provided no information used in `equals` comparisons on the object is modified. * * If two objects are equal according to the `equals()` method, then calling the `hashCode` method on each of the two objects must produce the same integer result. */ public open fun hashCode(): Int /** * Returns a string representation of the object. */ public open fun toString(): String }
According to the comments, Any is actually the same as Object in Java, that is to say, Any in Kotlin replaces Object in Java and becomes the parent class of all classes in Kotlin. But this statement is not very rigorous, because Any is not empty, and there is a Any?
in Kotlin
, which refers to the nullable Any
. Obviously, Any?
is the parent class of Any
, then strictly speaking, Any?
is the parent class of all classes, Any
is just the parent class of all non-nullable classes (that is, without ?).
Nothing
Nothing
is the most difficult concept to understand, different from Unit
as for Void
, Any
for Object
, Nothing
does not have a similar concept in Java. Nothing
is defined as follows:
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()
Nothing
is a class, and the class constructor is private, which means we cannot construct a Nothing
object from the outside. As mentioned above, every method has a return value, and the return value is at least one Unit
, which is for normal methods. If the return type of a method is defined as Nothing
, then this method cannot return normally. It can be understood that all methods in Koltin are expressions, that is, they all have return values, so normal methods return Unit
, and methods that cannot return normally return Nothing
. For example, define the following two methods:
fun test1(): Nothing{ while (true) {} } fun test2(): Nothing{ while (false) {} }
The test1()
method can be compiled and passed, but the program will always be caught in a loop and cannot return normally when it is executed; test2()
can return normally when it is executed at first glance , but because the return type is defined as Nothing
, this sentence is contradictory. It has been agreed that it cannot be returned normally (the return type is defined as Nothing
), and the internal logic of your method is fine. , returned to me, then there is a problem, so he actually failed to compile, and it is easy to understand: I need to return an object of class Nothing
, but because Nothing
The class is not open
, and the constructor is private, so there is no way to return an object of it. How to let him compile it? An exception can be thrown:
fun test2(): Nothing{ while (false) {} throw Exception() }
Well, now I still can’t return normally because I threw an exception, so I declare the return type as Nothing
and there is no problem. Similar usage, for example, there is a method TODO
in Kotlin:
fun test3() { TODO() } @kotlin.internal.InlineOnly public inline fun TODO(): Nothing = throw NotImplementedError()
Because it is necessary to throw an exception, it is destined to fail to return normally, so it returns the Nothing
type. The return value type of the test3()
method should be the default Unit
, or other self-defined return types, but in fact, because TODO()
is called code> , so a Nothing
is returned (not returned normally), so the compilation can pass, why? Some articles understand Nothing
as a subclass of all other classes, that is to say, Nothing
is a subclass of other classes, so you can use One returns Nothing
instead, so understanding is no problem. But there is a question, isn’t Kotlin & amp; Java single inheritance? If Nothing
is a subclass of all classes, wouldn’t that be multiple inheritance? In fact, there is a concept here, which I also recently learned in “Kotlin Core Programming”. In fact, “inheritance” and “subclassing” are two concepts. We say that class A inherits class B, that is, A extends B, which emphasizes some implementations in B, which can be reused in A; and class A is a class The subclass of B emphasizes that class A can be used where class B is needed. The angles of the two are different. Single inheritance means that from the perspective of inheritance, the top-level parent class of all classes is Any
(Object
in Java), so everyone can reuse the parent class existing implementations of . And subclassing can be replaced in all places that need to use the parent class. For example, if a method needs to return an Any
, then I actually return an Int
object , is also no problem. So, Nothing
can replace the return type of the original method, from the perspective of subclassing, because it can be replaced, so Nothing
is a subclass of all classes, which is the same as a single Inheritance is non-conflicting. Referring to this statement, there is also an emptyList
in Kotlin:
/** * Returns an empty read-only list. The returned list is serializable (JVM). * @sample samples.collections.Collections.Lists.emptyReadOnlyList */ public fun <T> emptyList(): List<T> = EmptyList internal object EmptyList : List<Nothing>...
Because Nothing
is a subclass of other types, according to the generic covariance, emptyList
can replace the place where List
is needed .
The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. Java skill treeHome pageOverview 108557 people are studying systematically