方法的输入参数可选<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 没有帮助。
我创建了一个由某些 类 实现的通用接口。看起来像:
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 没有帮助。