链接空安全运算符

Ask*_*613 5 groovy nullpointerexception

我的项目有如下代码:

params.stringValue?.trim().replaceAll('aa', 'a')
Run Code Online (Sandbox Code Playgroud)

我们预计,如果params.stringValue为空,这两者 trim()replaceAll()不会被调用.

但是我们NullPointerException在这一行上得到的结论replaceAll()是无法在null对象上调用.

我们必须将代码更改为:

params.stringValue?.trim()?.replaceAll('aa', 'a')
Run Code Online (Sandbox Code Playgroud)

为什么上面的第一个代码段不起作用?这是Groovy中的一个错误,它在一次遇到null之后继续评估表达式吗?

dsh*_*rew 8

我不认为你的假设是正确的.这个:

params.stringValue?.trim().replaceAll('aa', 'a')
Run Code Online (Sandbox Code Playgroud)

并不意味着:

if(params.stringValue is null)
   dont proceed to trim() and replaceAll()
Run Code Online (Sandbox Code Playgroud)

它意味着:

if(params.stringValue is null)
   skip trim() without complain but pass null to replaceAll()
Run Code Online (Sandbox Code Playgroud)

所以你需要说:

params.stringValue?.trim()?.replaceAll('aa', 'a')
Run Code Online (Sandbox Code Playgroud)

这将跳过这两者trim()replaceAll()如果传入的参数为null.


inj*_*eer 8

你的假设只是部分正确.

?-运算符不破的执行在空的情况下,它会阻止调用当前方法,并返回一个null代替,这就是为什么它也需要保护链的右手侧?


Wil*_*ill 5

实际上,这就是Groovy的工作方式,并且已经咬伤了其他人

println book?.author?.firstName?.trim()。concat(“很棒。”)

...

看着这行代码,我确定可以避免任何偷偷摸摸的NullPointerException。如果book,author或firstName为null,那么我将只输出null,而不必担心concat()方法。毕竟,如果trim()方法成功,则没有必要保护它的结果为null。那就是我错了。

至少经过讨论可以改变这一点:

a?.bc //您看到错误了吗?;)

我将得到一个NullPointerException。我的意思是,如果您使用null-safe?。运算符在链式表达式中必须使用所有属性,因为如果忘记放在某个地方,也会出现错误。如果Groovy可以检测到?,那就太好了。运算符在表达式中,如果看到运算符丢失,则会将其注入其他属性。因此,如果您输入

a?.b?.ef?.g //我忘了放?。.n“ f”属性a?.befg

Groovy可以使用一个真正的null安全表达式来修复它,如下所示:

a?.b?.e?.f?.g