java lambda::expression有什么问题?为什么?::和普通表达式之间有什么区别?

java lambda::expression有什么问题?为什么?::和普通表达式之间有什么区别?,java,lambda,nullpointerexception,Java,Lambda,Nullpointerexception,正如我们所知,我们可以在Java中使用xxx::yyy而不是()->xxx.yyy(),但是如果xxx为空,它们将不同 带有::的版本将引发NullPointerException,但是()->xxx.yyy()在实际调用函数之前不会引发异常 为什么会这样 我使用IntelliJ IDEA进行编码,如果代码可以使用:而不是->,那么IDE将显示一条警告,告诉我将其更改为使用:(即使这会导致NullPointerException) 我如何解决这个问题 其他相关代码: public static

正如我们所知,我们可以在Java中使用
xxx::yyy
而不是
()->xxx.yyy()
,但是如果
xxx
为空,它们将不同

带有
::
的版本将引发NullPointerException,但是
()->xxx.yyy()
在实际调用函数之前不会引发异常

为什么会这样

我使用IntelliJ IDEA进行编码,如果代码可以使用
而不是
->
,那么IDE将显示一条警告,告诉我将其更改为使用
(即使这会导致NullPointerException)

我如何解决这个问题

其他相关代码:

public static void main(String[] args) {
    Manager manager1 = new Manager();
    Manager manager2 = null;

    // both line 1 and line 2 are ok
    NullUtils.objectNullFieldNull(manager1, () -> manager1.getName(), "");
    NullUtils.objectNullFieldNull(manager1, manager1::getName, "");

    // line 1 is ok but line 2 will throw NullPointerException
    NullUtils.objectNullFieldNull(manager2, () -> manager2.getName(), "");
    NullUtils.objectNullFieldNull(manager2, manager2::getName, "");
}

如您所见,如果
xxx
为null,则
()->xxx.yyy()
将创建一个函数,该函数在被调用时将抛出NPE,但在创建且未调用该函数时不会抛出异常。但是
xxx::yyy
会立即抛出一个NPE。因此,如果您要在两者之间进行选择,并且不想抛出NPE,请使用
->
版本

然而,还有另一种选择。您的
objectNullFieldNull
方法写得有些混乱,因为作为第一个参数传递的对象与作为第二个参数传递的供应商没有明确的关系。(对我来说)第二个参数是使用第一个参数的函数似乎更自然,如下所示:

@Data
@Builder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
public class Manager {

    private String code;

    private String name;

    private String mobile;
}
public static <O, R> R objectNullFieldNull(O o, Function<? super O, R> field, R orv) {
    return o==null ? orv : objectNull(field.apply(o), orv);
}
还是像这样

objectNullFieldNull(manager2, Manager::getName, "")
如果
manager2
为空,则NPE也不会


Manager::getName
是一个
函数
,它接受一个管理器(或null)作为其参数,并尝试对其调用
getName()
。请参阅:引用特定类型的任意对象的实例方法。

我绝对希望
()->xxx.yyy()
xxx
为null的情况下抛出
NullPointerException
。相信我,
()->xxx.yyy()
即使xxx为null也可以,我已经运行了它,我相信你犯了错误。“相信我”这个词对我这样有经验的人不起作用-我30年来一直在取消对空指针的引用,每次都会抛出异常。
()->xxx.yyy()
创建一个函数,如果执行该函数,该函数将抛出NPE。但是如果函数被创建并且没有执行,它不会抛出NPE。而
xxx::yyy
如果
xxx
为空,则立即抛出NPE。但不确定实际问题是什么。如果您想避免NPE,请使用
->
版本。我知道它创建了一个函数。但OP声称它不会抛出NPE。如果你调用它创建的函数,它将抛出一个NPE。thx~你已经解决了我的问题我添加了另一个静态函数你建议我~我还有另一个问题:
Manager::getName
可以用作
函数你能给我一些参考链接或统计数据,我可以自己研究,或者给我一些关键字,我可以搜索吗在线,thx~非常感谢@khelwood
objectNullFieldNull(manager2, Manager::getName, "")
objectNullFieldNull(manager2, m -> m.getName(), "")