【问题标题】:Java 8 Guava Preconditions throwing NullPointerException while evaluating the exception message stringJava 8 Guava Preconditions 在评估异常消息字符串时抛出 NullPointerException
【发布时间】:2020-03-17 14:02:06
【问题描述】:

我有一个对象 myObject,我想确保它为空,否则我想打印一条带有对象 ID 的自定义消息。我有以下代码行试图实现相同的目标

Preconditions.checkArgument(Objects.isNull(myObject),
                        "This object is not null #%s.", myObject.getId());

当 myObject 不为空时,此条件可以正常工作。它抛出适当的异常消息。但是当对象确实为空时,我期望其余的代码会被执行,但是由于 myObject.getId() 调用,我得到了一个空指针异常。

guava 前置条件是否评估异常消息字符串而不管条件是否为真?

【问题讨论】:

  • 这与guava无关,即以任何方式计算的错误信息,不管它是否被打印。您可以将其写为... "This object is not null #%s.", myObject == null ? null: myObject.getId() - 因为在这种情况下您并不真正关心消息
  • 如 Javadoc 中所写,除了在方法引用的上下文中,不要使用 Objects.isNull,如 .filter(Objects::isNull)。相反,请使用Preconditions.checkArgument(myObject == null)
  • 3rd 方库方法比if(myObject != null) throw new IllegalArgumentException("This object is not null #" + myObject.getId()); 有什么优势?我的意思是,除了混淆正在发生的事情并导致问题中的错误之外?以及为什么有这个参数,而它应该总是null

标签: java-8 guava preconditions


【解决方案1】:

Preconditions.checkArgument(Objects.isNull(myObject),
                    "This object is not null #%s.", myObject.getId());

你必须看看按什么顺序发生了什么:

在任何对checkArgument() 的调用发生之前,它的所有参数都会被评估:

  • Objects.isNull(myObject)
  • 字符串
  • myObject.getId()

只有这样才能进行调用,如果在此评估期间发生异常,则调用不会首先发生。

只是为了完整性,正如在其他地方已经提到的那样:要走的路是 myObject == null ? null: myObject.getId(),因为它避免了在 null 对象的情况下取消引用。

【讨论】:

  • 是的,这回答了我所有的问题。非常感谢!
【解决方案2】:

你可以通过(例如)破解它:

static void test(Object myObject) {

    Preconditions.checkArgument(
        myObject == null, "This object is not null #%s.", myObject == null ? null : myObject.getId()
    );

}

条件:myObject == null ? myObject : myObject.hashCode() 仍然会被评估,总是;但是直到需要时才会计算错误消息本身。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-14
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    相关资源
    最近更新 更多