为什么我不能在Kotlin中将空值类型分配给Any?

时间:2019-02-19 06:50:12

标签: kotlin types null

任何人都可以解释为什么在Kotlin中这样做是不可能的吗?

val x :Int? = 123
val y :Any = x

我来自.NET背景,可将Nullable类型分配给Object类型,但是它们有何不同?

4 个答案:

答案 0 :(得分:5)

可空类型不是Any的子类型,但是它们是Any?的子类型。

Any只是不可为空类型的超类。这样就可以编写需要任何非空实例的代码,并且仍然受益于类型检查器的安全性(与使用Java的Object不同)。

这是一张可以提供帮助的图像:

enter image description here

以下代码可以有效替代您的代码:

val x: Int? = 123
val y: Any? = x

答案 1 :(得分:4)

从文档中

  

Kotlin的类型系统旨在消除代码(也称为The Billion Dollar Mistake.

)中空引用的危险。      

在Kotlin中,类型系统区分可以容纳null的引用(可为空的引用)和不能容纳null的引用(非null引用)。

示例:

var a: String = "abc"
a = null // compilation error

var b: String? = "abc" //using `String?` allows you to assign null
b = null // ok
print(b)

Any是与String相同的类,唯一的区别是每个类都具有Any作为其超类。但是我针对NPE撰写的上述内容适用于kotlin中的所有类型。

答案 2 :(得分:2)

是的。标记Kotlin变量的基本要求是是否可以为Null,以避免NPE。

在您的情况下,

var x: Int? = 123

被分配为可空值?但是,当您将其映射到Any对象时,您错过了添加nullable的可能?到任何物体

所以var y: Any? = x

将这样做,因为我们也将y标记为可空。

答案 3 :(得分:0)

代码val x :Int? = 123的第一行清楚地表明x应该具有类型Int的值 Kotlin提供了用于表示数字的内置类型Int

在下一行val y :Any = x上,y应该具有Any类型,它是Kotlin类层次结构的根。每个Kotlin类都有Any作为超类。

因此存在类型不匹配-因此Kotlin编译器抱怨无法将Int分配给声明为保留类型Any的对象