spring Optional orElse()在发生异常时无法返回替代值

lf3rwulv  于 2022-11-21  发布在  Spring
关注(0)|答案(3)|浏览(142)

我正在使用这个逻辑,如果没有找到雇员,则尝试返回new Employee()
但是,当request.getId()null时,它抛出异常,我等待它执行orElse()部分,但是它没有,那么,我应该使用另一个可选方法,例如orElseGet()ifPresentOrElse()吗?
如何以智能方式解决此问题?

Employee employee = employeeRepository.findById(request.getId())
        .orElse(new Employee());

***更新:***如果使用Optional不是一个好主意,我考虑使用以下方法:

Employee employee = new Employee();
if (id != null) {
    employee = employeeRepository.findById(id)
                   .orElse(new Employee());
}

有什么想法吗?

tzdcorbm

tzdcorbm1#

正如在注解中提到的,Optional在这种情况下不做任何事情。要解决这个问题,你需要自己处理null的值。你可以让request.getId()自己返回一个Optional(因为它可以是null)。
现在,您可以使用flatMap()运算符链接这些Optional

public class MyRequestClass {
    private Long id;

    // Change your getter to this, or make a new one, eg. 'getOptionalId()'
    public Optional<Long> getId() {
        return Optional.ofNullable(id);
    }
}

现在,您可以重构代码以:

Employee employee = request
    .getId()
    .flatMap(employeeRepository::findById) // Using flatMap() in stead of map()
    .orElseGet(Employee::new); // I changed this part so that new Employee() is 
                               // called lazily when no Employee was found in 
                               // the database (or when the request has no ID)
svgewumm

svgewumm2#

避免使用Optional来隐藏空检查

使用Optional来隐藏 * null检查 * -是反模式。
隐式 * 空值检查 * 没有什么错,例如if (something == null)Optional上的更多不是设计用于执行 * 空值检查
以下是Java和OpenJDK开发人员Stuart Marks对answer的引用:
Optional主要用途如下:(幻灯片36)
Optional旨在为库方法返回类型提供一种有限机制在这种情况下,明确需要表示“无结果",并且在这种情况下,使用null非常可能导致错误。
Optional链接方法的能力无疑是非常酷的,在某些情况下,它减少了条件逻辑的混乱。但通常情况下,这是行不通的。一个
典型的代码味道
是,它不是使用方法链接处理从某个方法返回的Optional,而是从可空的东西创建Optional。以便链接方法避免条件
重点是我 *)
从上面的引文中可以清楚地看到,Optional是在JDK中引入的,为返回类型提供了一个有限的机制。任何其他情况,如使用可选字段,将其存储到集合中,创建可选字段来替换空值检查或/和以便在其上链接方法,都被认为是Optional的滥用。
再看看Stuart Marks的另一个答案:Should Optional.ofNullable() be used for null check?
也就是说,当请求对象中的id可以是null时,通过id检索employee的更简洁的方法将如下:

public Employee getEmployeeById(Request request) {
    Long id = request.getId();
    
    if (id == null) return new Employee();

    return employeeRepository.findById(id)
            .orElse(new Employee());
}

如果new Employee()在代码中出现两次让fill不舒服,那么你可以这样重新实现它:

public Employee getEmployeeById(Request request) {
    Long id = request.getId();        
    Optional<Employee> result = Optional.empty();

    if (id != null) result = employeeRepository.findById(id);

    return id == null || result.isEmpty() ? new Employee() : result.get();
}
9q78igpj

9q78igpj3#

如何处理request.getId()的空值并避免陷入异常?
假设employeeRepository#findById传回Optional<Employee>,请使用下列其中一项:
第一个

相关问题