groovy - Groovy 注入(inject)中奇怪的 NullPointerException

标签 groovy nullpointerexception

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。

最佳答案

因为这段代码:

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

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

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

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

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

要了解为什么这是一个问题,请查看 inject 的内容方法确实如此。

引用 Javadoc:

Iterates through the given Collection, passing in the initial value to the 2-arg closure along with the first item. The result is passed back (injected) into the closure along with the second item. The new result is injected back into the closure along with the third item and so on until the entire collection has been used.

现在,让我们看一个稍微修改过的示例。我添加了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条件被评估为 false。因为没有else没有返回任何内容

什么都没有,由 null 表示闭包第一次求值返回的引用与列表的下一个元素一起用于第二次求值。

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

因此异常(exception)。

这是一个与有效版本等效的版本:

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

输出符合预期:

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

关于groovy - Groovy 注入(inject)中奇怪的 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27005152/

相关文章:

java - 可点击的 ListView

java - 动态加载 Groovy 类并调用管道脚本中的方法

java - 在 Groovy 中使用 Google-Reflection 会导致异常,而等效的 Java 代码可以工作

java - NetBeans 中的 Groovy/Grails 支持在哪里?

java - 添加框架内容时出现空指针异常

Java:不一致的 NullPointerException

java - 无法将 WebDriver 实例转换为 JavascriptExecutor

java - @Rule 声明会导致调试尝试出错

spring-boot - 来自 Gradle 任务的 HTTP 发布 - Groovy

groovy - class.getResourceAsStream ('*.groovy')