为什么应该在参数中使用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中打包一个参数,对于编译器来说是次优的,并且做了不必要的包装。
  • ( - )与可空参数相比,可选是更昂贵的。
  • 一般来说:可选统一了两个状态,必须将其解开。 因此,对于数据流的复杂性来说,它比输入更适合结果。



    没有使用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?