Kotlin中的Unit和Nothing
Unit
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"
}
Kotlin里面的Unit在类型上相当于Java里面的void,但是又有些不同。
- Java中的void是关键字。Unit本身是一个用
object
表示的单例,所以可以理解为Kotlin有一个类 - 在Kotlin中,一切方法/函数都是表达式。表达式是总是有值的,所以每一个方法都必有一个返回值。如果没有用
return
明确的指定,那么一般来说就会用自动帮我们加上Unit
fun method() :Unit{
}
fun method(){
}
上面的两个方法是相同的。:Unit
是可以省略的。
Nothing
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()
在Kotlin中,所有正常的方法都会有返回值,至少会有一个Unit返回,但是还有一种返回类型为Nothing的方法。这种方法是不正常的,或者说它会抛出异常。
凡事皆有实例。 你可以用Nothing来表示“一个从不存在的值”:例如: 如果函数的返回类型为Nothing,则意味着它永远不会返回(总是抛出异常)。
当我们定义一个函数,给出的返回类型是Nothing:
可以看出直接编译就报错了,对于编译器来说,你明明告诉他返回值不存在,可以你还return了一个值,他直接emo了…
这时候我们应该是抛出一个异常。可以下面这样修改:
fun main() {
method("抛出异常")
}
fun method(error:String) :Nothing{
throw Exception(error)
}
执行结果:
在Kotlin中类似的还有TODO
: TODO
函数 唯一的作用 就是 抛出异常
fun test3(){
TODO()
}
@kotlin.internal.InlineOnly
public inline fun TODO(): Nothing = throw NotImplementedError()
这个TODO函数可以在任何函数下抛出异常。不过如果你足够细心会发现test3()
方法返回值类型应该是默认的 Unit
,或者其他自己定义的返回类型,但实际上因为调用了 TODO()
,所以返回了一个 Nothing
(并没有正常返回),这样编译是可以通过的,为什么呢?
有一些文章是把
Nothing
当做其他所有类的子类来理解的,也就是说Nothing
是其他类的子类,所以返回其他类的地方可以用一个返回Nothing
来代替,这样理解也是没问题的。但是就有疑问了,Kotlin&Java不是单继承的吗?如果Nothing
是所有类的子类,那不就是多继承了?其实这里有一个概念。其实“继承”和“子类化”是两个概念,我们说类A继承了类B,即 A extends B,是强调B中的一些实现,可以在A中复用;而说类A是类B的子类,是强调在需要类B的地方可以用类A代替。两者的角度不一样。单继承,指的是从继承的角度上,一切类的顶级父类都是Any
(Java中是Object
),那么大家都可以复用父类的现有实现。而子类化,则是在所有需要用到父类的地方可以代替,比如一个方法我需要返回一个Any
,那么我实际上返回一个Int
对象,也是没问题的。所以说,Nothing
可以代替原方法的返回类型,是从子类化的角度,因为可代替,所以Nothing
是所有类的子类,这和单继承是没冲突的。