【问题标题】:Weird NullPointerException in Groovy injectGroovy 注入中奇怪的 NullPointerException
【发布时间】:2015-01-16 06:44:43
【问题描述】:
groovy:000> ['homepages/gg','a','b','c','d'].inject([]) { list, conf -> if (!conf.contains('homepage')) { list << conf.trim() } }
ERROR java.lang.NullPointerException:
Cannot invoke method leftShift() on null object
        at groovysh_evaluate$_run_closure1.doCall (groovysh_evaluate:3)
groovy:000> ['homepages/gg','a','b','c','d'].inject([]) { list, conf -> conf.contains('homepage') ? list : list << conf.trim() }
===> [a, b, c, d]

为什么我在第一种情况下得到NullPointerException 而在第二种情况下却没有?我正在使用 Groovy 2.3.7。

【问题讨论】:

  • 也可以写成:theList.findAll{!it.contains('homepages')}*.trim()
  • 谢谢!更时髦的喜欢:)

标签: groovy nullpointerexception


【解决方案1】:

因为这段代码:

if (!conf.contains('homepage')) { list << conf.trim() }

不满足条件时不返回任何内容。这个if 没有else。如果您添加一个返回有意义值的else,您将避免该异常。

另一方面,无论是否满足条件,三元运算符都会返回一个值,因此以下代码:

conf.contains('homepage') ? list : list << conf.trim()

即使conf 确实包含'homepage',也会返回一个实际对象

要了解为什么会出现此问题,请查看 inject 方法的作用。

引用 Javadoc:

遍历给定的 Collection,将初始值与第一项一起传递给 2-arg 闭包。结果与第二个项目一起传回(注入)到闭包中。新结果与第三个项目一起被注入回闭包中,以此类推,直到整个集合被使用。

现在,让我们看一个稍作修改的示例。我加了一个println 看看闭包参数变成了什么:

 ['homepages/gg','a','b','c','d'].inject([]) { list, conf -> println "[$list, $conf]"; if (!conf.contains('homepage')) { list << conf.trim() } }

运行这个会产生:

[[], homepages/gg]
[null, a]
Exception thrown

java.lang.NullPointerException: Cannot invoke method leftShift() on null object

    at ConsoleScript9$_run_closure2.doCall(ConsoleScript9:2)

    at ConsoleScript9.run(ConsoleScript9:2)

第一次调用将您作为单个Object 参数传递的空数组和列表的第一个元素,即"homepages/gg"。这将传递给 if 表达式。因为第一个元素"homepages/gg" 确实包含字符串"homepage",所以if 条件被评估为假。因为没有else什么都不返回

nothing,由 null 引用表示,由闭包的第一次评估返回,与列表的下一个元素一起用于第二次评估。

conf 现在等于 "a" 并且 list 等于 null。此外,您可以在 null 列表 (list &lt;&lt; conf.trim()) 上使用 &lt;&lt; 左移运算符。

因此例外。

这是一个等效的版本:

['homepages/gg','a','b','c','d'].inject([]) { list, conf ->  if (!conf.contains('homepage')) { list << conf.trim() } else list }

输出如预期:

===> [a, b, c, d]

【讨论】:

  • 很好的解释!谢谢。绝对有帮助:)
猜你喜欢
  • 1970-01-01
  • 2014-01-11
  • 1970-01-01
  • 2018-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
  • 1970-01-01
相关资源
最近更新 更多