为什么应该在参数中使用Java 8的Optional
我在很多网站上阅读过可选应该只用作返回类型,而不是在方法参数中使用。 我努力寻找合乎逻辑的原因。 例如,我有一块逻辑有2个可选参数。 因此,我认为这样写我的方法签名是有意义的(解决方案1):
public int calculateSomething(Optional<String> p1, Optional<BigDecimal> p2 {
// my logic
}
许多网页指定可选不应该用作方法参数。 考虑到这一点,我可以使用下面的方法签名并添加一个清晰的Javadoc注释来指定参数可能为空,希望未来的维护者将读取Javadoc,并因此始终在使用参数之前执行空检查(解决方案2) :
public int calculateSomething(String p1, BigDecimal p2) {
// my logic
}
或者,我可以用四种公共方法替换我的方法,以提供更好的界面,并使其更明显p1和p2是可选的(解决方案3):
public int calculateSomething() {
calculateSomething(null, null);
}
public int calculateSomething(String p1) {
calculateSomething(p1, null);
}
public int calculateSomething(BigDecimal p2) {
calculateSomething(null, p2);
}
public int calculateSomething(String p1, BigDecimal p2) {
// my logic
}
现在我尝试编写为每种方法调用这段逻辑的类的代码。 我首先从另一个返回Optional
的对象中检索两个输入参数,然后调用calculateSomething
。 因此,如果使用解决方案1,调用代码将如下所示:
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1, p2);
如果使用解决方案2,调用代码将如下所示:
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1.orElse(null), p2.orElse(null));
如果解决方案3被应用,我可以使用上面的代码,或者我可以使用下面的代码(但它是更多的代码):
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result;
if (p1.isPresent()) {
if (p2.isPresent()) {
result = myObject.calculateSomething(p1, p2);
} else {
result = myObject.calculateSomething(p1);
}
} else {
if (p2.isPresent()) {
result = myObject.calculateSomething(p2);
} else {
result = myObject.calculateSomething();
}
}
所以我的问题是:为什么使用Optional
s作为方法参数被认为是不好的做法(请参阅解决方案1)? 它看起来对我来说是最可读的解决方案,并且使得最明显的是参数对于未来的维护者可能是空的或空的。 (我知道Optional
的设计者打算将它仅用作返回类型,但我无法找到任何合理的理由不在此场景中使用它)。
哦,这些编码风格应该带点盐。
一般来说:可选统一了两个状态,必须将其解开。 因此,对于数据流的复杂性来说,它比输入更适合结果。
没有使用Optional作为参数几乎没有好的理由。 反对此的论点依赖于权威的论据(参见Brian Goetz-他的论点是我们不能强制执行非null选项)或者Optional参数可能为null(本质上是相同的论点)。 当然,Java中的任何引用都可以为空,我们需要鼓励编译器执行的规则,而不是程序员的内存(这是有问题的并且不能缩放)。
函数式编程语言鼓励可选参数。 使用它的最好方法之一是具有多个可选参数,并使用liftM2使用函数,假定参数不为空并返回可选参数(请参见http://www.functionaljava.org/javadoc/4.4/functionaljava/fj /data/Option.html#liftM2-fj.F-)。 不幸的是,Java 8实现了一个支持可选的非常有限的库。
作为Java程序员,我们应该只使用null与遗留库进行交互。
链接地址: http://www.djcxy.com/p/8855.html上一篇: Why should Java 8's Optional not be used in arguments
下一篇: How to document (simple) preconditions of a Java method?