一尘不染

为什么在参数中不使用Java 8的Optional

java

我已经在许多网站上阅读了Optional应该仅用作返回类型,而不能在方法参数中使用。我正在努力寻找一个合理的理由。例如,我有一段逻辑,其中包含2个可选参数。因此,我认为这样写我的方法签名(解决方案1)会很有意义:

public int calculateSomething(Optional<String> p1, Optional<BigDecimal> p2 {
    // my logic
}

许多指定为Optional的网页不应用作方法参数。考虑到这一点,我可以使用以下方法签名并添加清晰的Javadoc注释以指定参数可以为null,希望将来的维护者将读取Javadoc,因此始终在使用参数之前进行null检查(解决方案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
}

现在,我尝试编写该类的代码,每种方法都会调用此逻辑。我首先从另一个返回Optionals的对象中检索两个输入参数,然后调用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();
    }
}

所以我的问题是:为什么将Optionals用作方法参数被认为是不好的做法(请参阅解决方案1)? 对于我来说,这似乎是最易读的解决方案,并且最明显的是,对于将来的维护者,参数可以为空/空。(我知道设计人员Optional打算将其仅用作返回类型,但是在这种情况下我找不到任何不使用它的逻辑原因)。


阅读 751

收藏
2020-03-03

共1个答案

一尘不染

这些编码风格需要花些力气。

  1. (+)将Optional结果传递给另一种方法,而无需任何语义分析;将其留给方法,是完全可以的。
  2. (-)使用可选参数在方法内部引起条件逻辑实际上是相反的。
  3. (-)需要将参数打包在Optional中,对于编译器而言不是最佳选择,并且不需要进行包装。
  4. (-)与可为空的参数相比,可选的成本更高。

通常:Optional统一了两个状态,必须对其进行详细说明。因此,对于数据流的复杂性,比输入更适合结果。

2020-03-03