方法的输入参数可选<T>

Optional<T> for an input parameter of a method

我创建了一个由某些 类 实现的通用接口。看起来像:

public interface KingdomElementService<T> {

  public T findById(Long id);

  public T save(Optional<T> object);

  public void update(T t);

}

我的 IntelliJ 在保存时大喊大叫,写入 "Optional is used as a parameter."。我理解这样的逻辑,即接受可能存在和可能不存在的事物是很奇怪的。为什么我考虑这样做是为了重写一些

 if(something){
   do();
 }
 else{
 throw new Expression();
 }

something.orElseThrow(Expression::new);

现在我想知道我使用 Optional 的解决方案在这里是否有点矫枉过正。你怎么看?我应该考虑改回来吗?

当你有像 save(Optional<T> object);

这样的方法时

我仍然可以打电话save(null);这就是为什么这里的可选没有意义。

您可以在您的方法中实现一个简单的 null 检查

void save(T object){
        if(object == null){
            // do smth
        }
    }

或者在方法内部使用Optional.ofNullable()

void save(T object){
    Optional.ofNullable(object)
        .map(..)
    .orElseGet(IllegalAccessError::new);
}

没有针对 Optional 的具体内容,但是通过将其用作参数,您将强制所有调用者将 Optional 传递给此方法。我宁愿为此使用 @Nullable,例如:

public T save(@Nullable T object);

这意味着您必须编写 if..else 块(或三元运算符),但在我看来,这样做的复杂性远低于强迫您的客户传递 Optional.

此外,如果您想使用相同的控制结构,您可以将 Optional.of(object); 作为方法实现的第一行,并将其用于方法代码的其余部分。

Java 语言架构师都认为 Optional 应该只用作 return 类型。这是为了表示 return 类型可能是 null。所以要小心。

Optional 作为输入参数将要求您始终检查参数是否存在,添加一些检查。如果你想添加任何验证,你也可以不带 Optional 。将输入参数标记为可选没有额外的价值。

另外,将参数传递给另一个接受 Optional 的方法的调用方法必须包装 Object 并发送。这是开销。

我没有考虑边缘情况。

编辑:从 'Java language is quite clear' 更改为更真实的东西。

似乎如果您有 KingdomElementService<T> 的实例,您希望 save 的调用者可以选择是否传递 T 的实例。因此,给定一些变量:

KingdomElementService<T> kes = ... ;
T someT = ... ;

呼叫者可以这样做:

kes.save(Optional.of(someT)); // 1
kes.save(Optional.empty());   // 2

这给来电者带来了不便。相反,您应该修改 KingdomElementService 以提供 save 方法的重载:一个带参数,一个不带参数:

interface KingdomElementService<T> {
    T save(T t);
    T save();
}

如果这样做,调用者就不必费心将所有内容包装在 Optional:

kes.save(someT); // 1
kes.save();      // 2

本质上,Optional 对想要采用可选参数的 API 没有帮助。