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

查看:323
本文介绍了为什么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注释来指定参数可能为null,希望将来的维护者将读取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
}

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

所以我的问题是:为什么呢认为使用可选 s作为方法参数的不良做法(参见解决方案1)?它看起来像是对我来说最易读的解决方案并且使参数最明显未来的维护者可能是空的/ null。 (我知道 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. ( - )与可空参数相比,可选性更高。

  1. (+) Passing an Optional result to another method, without any semantic analysis; leaving that to the method, is quite alright.
  2. (-) Using Optional parameters causing conditional logic inside the methods is literally contra-productive.
  3. (-) Needing to pack an argument in an Optional, is suboptimal for the compiler, and does an unnecessary wrapping.
  4. (-) In comparison to nullable parameters Optional is more costly.

一般情况下:可选统一两个状态,必须解开。因此,对于结果比输入更适合数据流的复杂性。

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天全站免登陆