无安全的好处

时间:2018-03-28 14:18:42

标签: null kotlin

我是Kotlin的新手,我读到它似乎是车轮之后的最佳发明。这无论如何都让我怀疑,当然因为我不理解这个概念所暗示的一切。

为了恢复我理解的内容,在我们NullPointerException之前,对代码中的某些内容有一个非常明确的想法,问题出在哪里但不是设置null的地方。无论如何,很明显我们可以在这里等待,直到空指针回来期待理解从回溯发生的事情。每个人都已经这样做了,这绝不是不可能找到的。

现在使用Null指针安全性,我们不再有这样的崩溃,只是在我们的应用程序中默认不会执行的代码的一部分(我们假设使用的引用不应该像以前一样为null)导致可能比以前的NullPointerException更难理解的奇怪行为,或者可能只是某些任务在某人意识到之前没有执行的任务。

Null Pointer Safety提供的好处是什么?

5 个答案:

答案 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,并且当它被破坏时得到一个编译(而不是运行时)错误。

如何在Kotlin中获取NullPointerException

仍然可以获得空指针,但主要方式是这样的:

  • 创建可空类型

    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问题。它只是主动强迫你做出明确的决定来防止它。