java - 如何将代码重写为可选项?

标签 java nullpointerexception java-8 option-type

在我目前的工作中,我们正在为 Java 8 重写一些代码。 如果您有这样的代码:

if(getApi() != null && getApi().getUser() != null 
     && getApi().getUser().getCurrentTask() != null)  
{
   getApi().getUser().getCurrentTask().pause();
}

你可以简单地把它改写成

Optional.ofNullable(this.getApi())
.map(Api::getUser)
.map(User::getCurrentTask)
.ifPresent(Task::pause);

不改变代码行为。 但是,如果中间的某些东西因为未检查为空而可能抛出 NPE 怎么办?

例如:

if(getApi() != null && getApi().getUser() != null 
     && getApi().hasTasks())  
{
   getApi().getMasterUser(getApi().getUser()) //<- npe can be here
     .getCurrentTask().pause();
}

使用可选值重写这样的代码的最佳方法是什么?(它应该完全相同并在 getMasterUser(...) 返回 null 时抛出 npe)

UPD 第二个例子:

if(getApi()!=null && getApi.getUser() != null)
{
   if(getApi().getUser().getDepartment().getBoss() != null)// <- nre if department is null
     {
        getApi().getUser().getDepartment().getBoss().somefunc();
     }
 }

它有 api、用户、老板的 nullchecks,但没有部门。如何使用可选项制作它?

最佳答案

if(getApi() != null && getApi().getUser() != null) {
    if(getApi().getUser().getDepartment().getBoss() != null) {
        getApi().getUser().getDepartment().getBoss().somefunc();
    }
}

用可选值写这个的一种方法是:

Optional.ofNullable(this.getApi())
    .map(Api::getUser)
    .map(user -> Objects.requireNonNull(user.getDepartment()))
    .map(Department::getBoss)
    .ifPresent(Boss::somefunc);

但这很容易出错,因为它需要客户端跟踪什么是可选的,什么不是可选的。更好的方法是让 api 本身返回一个可选值而不是可为 null 的值。那么客户端代码为:

this.getApi()
    .flatMap(Api::getUser)
    .map(user -> user.getDepartment().getBoss())
    .ifPresent(Boss::somefunc));

这将使在 api 中更清楚哪些值应该是可选的,并使不处理它们成为编译时错误。

if(getApi() != null && getApi().getUser() != null && getApi().hasTasks()) {
    getApi().getMasterUser(getApi().getUser()).getCurrentTask().pause();
}

在这里,您需要同时访问 apiuser,因此您可能需要嵌套 lambda:

getApi().filter(Api::hasTasks).ifPresent(api -> {
    api.getUser().ifPresent(user -> {
        api.getMasterUser(user).getCurrentTask().ifPresent(Task::pause);
    });
});

关于java - 如何将代码重写为可选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31500254/

相关文章:

java - 仅从 POM.xml 获取 MavenProject - pom 解析器?

java - 将本地时间转换为 UTC,反之亦然

android - Kotlin:EditText 在 afterTextChanged() 中为空

java - 如何使用 Java 8 添加 HashMap 中包含的 BigDecimals?

java - LocalDate - 解析区分大小写

java - Java 中的分支和循环(break 和 continue)

java - 我如何在工具栏的图标和标题之间设置空格

java - 什么是NullPointerException,我该如何解决?

java - 开始 : Applet not initialized error in NetBeans IDE 8. 0

java - 试图理解 Java8 中流的 distinct()