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

pnwntuvh  于 2021-07-07  发布在  Java
关注(0)|答案(1)|浏览(352)

关闭。这个问题需要细节或清晰。它目前不接受答案。
**想改进这个问题吗?**通过编辑这个帖子来添加细节并澄清问题。

上个月关门了。
改进这个问题

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, "");
}

我们知道,我们可以利用 ::yyy 而不是 () -> .yyy() 在java中,但是如果 `` 如果为空,则它们将不同。
具有的版本 :: 将引发nullpointerexception,但是 () -> .yyy() 在函数实际被调用之前不抛出异常。
为什么会这样?
我用intellij的思想来编码,如果代码可以使用 :: 而不是 -> ,则ide将显示一个警告,告诉我将其更改为使用 :: (即使这会导致nullpointerexception)。
如何解决此问题?
其他相关代码:

public class NullUtils {

    public static <O, R> R objectNullFieldNull(O o, Supplier<R> supplier, R orv) {
        return Objects.isNull(o) ? orv : objectNull(supplier.get(), orv);
    }

    public static <O> O objectNull(O original, O target) {
        return Objects.isNull(original) ? target : original;
    }
}
@Data
@Builder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
public class Manager {

    private String code;

    private String name;

    private String mobile;
}
rslzwgfq

rslzwgfq1#

如你所见,如果 `` 则为空 () -> .yyy() 创建一个函数,该函数在被调用时将抛出npe,但在创建但未调用该函数时不抛出异常。但是 ::yyy 立即抛出npe。因此,如果你在两者之间做出选择,并且不想抛出npe,请使用 -> 版本。
不过,还有另一种选择。你的 objectNullFieldNull 方法的编写有些混乱,因为作为第一个参数传递的对象与作为第二个参数传递的供应商没有明确的关系。在我看来,第二个参数是使用第一个参数的函数更为自然,如下所示:

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, "")

或者像这样

objectNullFieldNull(manager2, m -> m.getName(), "")

npe也不会 manager2 为空。 Manager::getName 是一个 Function<Manager, String> 接受管理器(或null)作为其参数,并尝试调用 getName() 在上面。请参阅方法引用:对特定类型的任意对象的示例方法的引用。

相关问题