具有供应商参数性能的Java 8 requireNonNull方法

use*_*900 3 java string object java-8 null-check

Java 8中添加了带有Objects.requireNonNull的方法Supplier,但是我不确定声明的性能改进是什么:

尽管这在非null情况下可能会带来性能优势,但是在决定调用此方法时,应注意创建消息提供者的成本要比直接创建字符串消息的成本要低。

带String的方法如果不为null则忽略参数:

public static <T> T requireNonNull(T obj, String message) {
    if (obj == null)
        throw new NullPointerException(message);
    return obj;
}
Run Code Online (Sandbox Code Playgroud)

我发现了JDK-8011800:添加java.util.Objects.requireNonNull(T,Supplier)

在JDK 7中,java.util.Objects包括几种检查null的方法,其中包括一种方法,该方法接受一条消息以返回是否找到null。对于JDK 8中的lambda,要包括的另一个变体是requireNonNull方法,该方法采用字符串提供程序而不是字符串。因此,对于非null情况,可以避免创建字符串消息的成本。请注意,lambda捕获的费用可能会为非零。

有注释表示对性能没有影响:

非零捕获成本确实让我担心。我担心它会经常消除使用供应商的任何优势。 2013/09/04

我发现了其他问题,但没有提到(为什么)发送String参数会降低性能

它专用于lambda表达式/流用法吗?

mar*_*ran 5

考虑一下这一点,generateString为了从中生成字符串,在哪里做了很多工作someParam

Objects.requireNonNull(obj, generateString(someParam));
Run Code Online (Sandbox Code Playgroud)

参数在Java中热切地求值,这意味着generateString将在requireNonNull调用之前求值。因此,无论是否obj为null ,都将对其进行计算。

您可以通过将其更改为此来解决此问题:

Objects.requireNonNull(obj, () -> generateString(someParam));
Run Code Online (Sandbox Code Playgroud)

在这种情况下,generateString仅当obj实际上为null 时才被调用。当generateString它比创建Supplier-object 昂贵时,效率更高。

如果您的String参数只是一个文字,则应该只使用常规的非lambda方法,例如:

Objects.requireNonNull(obj, "obj was null!");
Run Code Online (Sandbox Code Playgroud)