为什么不应该在参数中使用 Java 8 的 Optional [英] Why should Java 8's Optional not be used in arguments

查看:32
本文介绍了为什么不应该在参数中使用 Java 8 的 Optional的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在很多网站上都读过 Optional 应该只用作返回类型,而不是在方法参数中使用.我正在努力寻找一个合乎逻辑的原因.例如,我有一个逻辑,它有 2 个可选参数.因此,我认为像这样编写我的方法签名是有意义的(解决方案 1):

I've read on many Web sites Optional should be used as a return type only, and not used in method arguments. I'm struggling to find a logical reason why. For example I have a piece of logic which has 2 optional parameters. Therefore I think it would make sense to write my method signature like this (solution 1):

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

许多网页指定 Optional 不应用作方法参数.考虑到这一点,我可以使用以下方法签名并添加清晰的 Javadoc 注释来指定参数可能为空,希望未来的维护者能够阅读 Javadoc,因此在使用参数之前始终执行空检查(解决方案 2):

Many web pages specify Optional should not be used as method arguments. With this in mind, I could use the following method signature and add a clear Javadoc comment to specify that the arguments may be null, hoping future maintainers will read the Javadoc and therefore always carry out null checks prior to using the arguments (solution 2):

public int calculateSomething(String p1, BigDecimal p2) {
    // my logic
}

或者,我可以用四个公共方法替换我的方法,以提供更好的接口并使其更明显 p1 和 p2 是可选的(解决方案 3):

Alternatively I could replace my method with four public methods to provide a nicer interface and make it more obvious p1 and p2 are optional (solution 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,调用代码将如下所示:

Now I try writing the code of the class which invokes this piece of logic for each approach. I first retrieve the two input parameters from another object which returns Optionals and then, I invoke calculateSomething. Therefore, if solution 1 is used the calling code would look like this:

Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1, p2);

如果使用解决方案 2,调用代码将如下所示:

if solution 2 is used, the calling code would look like this:

Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1.orElse(null), p2.orElse(null));

如果应用了解决方案 3,我可以使用上面的代码,或者我可以使用以下代码(但它的代码要多得多):

if solution 3 is applied, I could use the code above or I could use the following (but it's significantly more code):

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 的设计者打算将它仅用作返回类型,但我找不到在这种情况下不使用它的任何合乎逻辑的理由).

So my question is: Why is it considered bad practice to use Optionals as method arguments (see solution 1)? It looks like the most readable solution to me and makes it most obvious that the parameters could be empty/null to future maintainers. (I'm aware the designers of Optional intended it to only be used as a return type, but I can't find any logical reasons not to use it in this scenario).

推荐答案

哦,这些编码风格需要加点盐.

Oh, those coding styles are to be taken with a bit of salt.

  1. (+) 将一个 Optional 结果传递给另一个方法,没有任何语义分析;把它留给方法,很好.
  2. (-) 在方法中使用导致条件逻辑的可选参数实际上是适得其反的.
  3. (-) 需要在 Optional 中打包参数,这对编译器来说是次优的,并且会进行不必要的包装.
  4. (-) 与可为空的参数相比,Optional 的成本更高.
  5. (-) 有人在实际参数中将 Optional 传递为 null 的风险.

一般来说:Optional 统一了两个必须被解开的状态.由于数据流的复杂性,因此更适合结果而不是输入.

In general: Optional unifies two states, which have to be unraveled. Hence better suited for result than input, for the complexity of the data flow.

这篇关于为什么不应该在参数中使用 Java 8 的 Optional的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆