我是Kotlin的新手,我读到它似乎是车轮之后的最佳发明。这无论如何都让我怀疑,当然因为我不理解这个概念所暗示的一切。
为了恢复我理解的内容,在我们NullPointerException
之前,对代码中的某些内容有一个非常明确的想法,问题出在哪里但不是设置null的地方。无论如何,很明显我们可以在这里等待,直到空指针回来期待理解从回溯发生的事情。每个人都已经这样做了,这绝不是不可能找到的。
现在使用Null指针安全性,我们不再有这样的崩溃,只是在我们的应用程序中默认不会执行的代码的一部分(我们假设使用的引用不应该像以前一样为null)导致可能比以前的NullPointerException
更难理解的奇怪行为,或者可能只是某些任务在某人意识到之前没有执行的任务。
Null Pointer Safety提供的好处是什么?
答案 0 :(得分:4)
主要好处是可能导致NullPointerException
的代码无法编译。当您获得“无声执行的代码的一部分”时,唯一的情况是您使用安全调用来处理潜在的可空性错误。这不是处理此类错误的唯一方法,也不是最有用的方法。
答案 1 :(得分:4)
我将假设您来自Java,您已经在其他地方查看了一些解释并且没有完全理解它们。因此,我不会试图给你一个全面的解释(你可以在其他地方找到),但我会尝试弄清楚空指针安全的核心思想。
有两点,如果你了解它们,应该说得足够清楚。首先,有两种不同类型的概念来表示你在Java中作为单一类型建模的东西:可空的而不是可空的。举个例子,在Java中你把一个字符串放在一个String
对象中,如果字符串可以为null则不关心,在Kotlin中你有两种类型:String?
和{{1} }。第一个接受空值(如Java等价物),但第二个不接受。因此,您可以在String
类型(例如?
或String?
)中使用空值,但是对于您可以使用的内容有很多限制:基本上您只限于你可以用null做的事情,因为毕竟变量可能持有一个空值。例如,没有调用方法。所以,虽然在Java中你可以在它上面调用一个方法并且有时候有一个Int?
,但在Kotlin你不能调用任何方法。这不是因为Kotlin的一些沉默行为,它比这简单得多:编译器不会让你。尝试,你会看到该程序无法编译。如果变量的类型为NullPointerException
而不是String
,那么Kotlin将允许您从中调用方法。
所以,基本上,没有空指针异常,因为你永远不能在一个可能为null的对象变量上调用一个方法。
但是,有时变量不是null:那么在变量不为null的情况下,如何调用变量上的方法呢?同样,答案很简单:你必须检查它。我的意思是,你必须使用String?
指令(显式或隐式)来检查变量是否为空。像“if
”之类的东西。所以,正如你所看到的,Kotlin编译器足够聪明,可以看到你使用if (myVariable != null) {call method on variable}
指令来保证变量不为null,因此它允许你调用{{}之间块中变量的方法。 1}}和if
。换句话说,如果您的变量属于{
类型,但是您位于}
块中,并且您检查到该变量不为空,那么Kotlin会将其视为String?
类型的变量而不是if
当你谈论
时某些部分是默默无法执行的代码
我猜你正在考虑一些内部隐含String
的运算符,比如String?
运算符。如果你写
if
意味着大致
?.
所以,实际上,如果变量为null,它将以静默方式“失败”。但如果您使用相同类型的myVariable?.call()
,这与Java没有什么不同。换句话说,如果变量为null,则不会发生任何事情,因为您明确地将其编码为行为类似。
答案 2 :(得分:0)
由于null对象,您不需要执行某些代码。
Null指针安全系统的好处是,您可以事先知道您是否可能面对Null Pointer
,并采取相应行动。您可以确定某些内容是否为空,并执行不同的操作。
例如:
var nullableServiceVariable: NullableService? = null //Let's say that you initialize this somewhere
var serviceAnswer = nullableServiceVariable?.answer ?: "Answer for null!"
编译器使您可以处理null
的可能性,因此您不会得到意外的NullPointerException来停止所有应用程序。如果nullable确实为null,我将给出一个替代分支,以便我的系统仍然可用。
如果您愿意,可以根据需要抛出NullPointerException
,但最好使用不可为空的变量:
var serviceAnswer = nullableServiceVariable!!.answer
如果变量为null, !!
将为您抛出一个NPE。
答案 3 :(得分:0)
在大多数语言中,这是允许的
val example: String = null
然后你会这样做:
print(example.toUpperCase());
你可以看到错误可能在第一位代码中,但错误发生在第二位,这令人困惑。
使用null安全性,当你定义一个变量时,你会说它是否为null,并且当它被破坏时得到一个编译(而不是运行时)错误。
仍然可以获得空指针,但主要方式是这样的:
创建可空类型
var r:String
将值设为null
r = null
断言值不为空
r!!
这就是为什么你要避免使用!!
,除非你确定该值不为空。
如果您不希望以多种方式使用null,则可以处理可空类型:
使用默认
val set = nullable ?: "It was null, sorry"
如果值为null则抛出
val set = nullable ?: throw AssertionError(":(")
传播空值
val set = nullable?.doThing()?.doThing2()?.property
set将是最终值,如果其中任何一个返回null,则为null
仅对空值进行操作
nullable?.let {
print(it.property)
}
答案 4 :(得分:0)
为了给你一个简短的答案,你的理解是完全正确的。 Kotlin没有解决 NPE问题。它只是主动强迫你做出明确的决定来防止它。