返回多个值的Java方法的最佳实践?

Ste*_*ers 10 java methods return class object

我需要一个非静态实例方法来返回多个值.举个简单的例子起见,让我们说的这些都是boolean successObject obj-但在一般情况下,有可能是更多,他们可能是彼此无关.可以想到几种不同的方法:

解决方案1

private boolean aMethod(int aParam, Object obj) { ...set obj parameter & return value... }
Run Code Online (Sandbox Code Playgroud)

解决方案2

private Pair<Boolean, Object> aMethod(int aParam) { ...set return pair values... }
Run Code Online (Sandbox Code Playgroud)

解决方案3

private Object obj;
...
private boolean aMethod(int aParam) { ...set obj field & return value... }
Run Code Online (Sandbox Code Playgroud)

解决方案4

private class MethodReturn { // Nested class - could be a separate class instead
    boolean success;
    Object obj;
    // ... Getters and setters omitted for brevity
}

private MethodReturn aMethod(int aParam) { ...set return object values... }
Run Code Online (Sandbox Code Playgroud)

我可能错过了更多的可能性吗?任何人都可以对每个人的利弊进行评论(理想情况下,在大多数情况下最好使用哪些)?

aro*_*ros 7

一般情况下,我会根据具体情况选择第4个地图或地图,但如果您需要返回多个不相关的值,我认为您有严重的设计问题(请访问https://en.wikipedia.org/ wiki/Single_responsibility_principle)

在特定情况下(在您的评论之后),我肯定会使用第4个建模响应所有必填字段.也可以使用ResponseSuccessful和ResponseFailure进行子类型化.

  • @chrylis:并不总是一个好的选择,例如来自函数式编程POV,抛出异常就像是一个`goto`跳转.使用`E E,T>`,`Optional <T>`或回调来处理错误会更好. (2认同)
  • 我同意仅在特殊情况下才应使用例外,而不是出于验证失败等常见原因.显然,真实世界的应用程序(和框架!)并不总是同意这一点! (2认同)

cha*_*lie 5

解决方案5 —回调

通过回调,您甚至可以返回多个2元组

private void aMethod(int aParam, BiConsumer<Boolean, String> callback) {
    …
    callback.accept(success1, msg1);
    …
    callback.accept(success2, msg2);
    …
}
Run Code Online (Sandbox Code Playgroud)

用法:

aMethod(42, (success, msg) -> {
    if (!success) {
        log.error(msg);
    }
});
Run Code Online (Sandbox Code Playgroud)

另外,您可以按组成返回(n> 2)元组,而无需自定义类-例如,对于4元组:

<A, B, C, D> void aMethod(int aParam, BiFunction<A, B, BiConsumer<C, D>> callback) {
    callback.apply(a, b).accept(c, d);
}

aMethod(42, (a, b) -> (c, d) -> log.debug("" + a + b + c + d));
Run Code Online (Sandbox Code Playgroud)

要评论您的解决方案:

  • 解决方案1:修改参数是不好的做法,而且,String是不可变的
  • 解决方案2:常用模式a Pair<T,U>或aTuple2<T,U>
  • 解决方案3:脆弱且不鼓励使用,它具有状态填充(并发等)的所有缺点。
  • 解决方案4:类似于#2,例如class MethodReturn implements Pair<Boolean, String> {}

注意:MethodReturn可以是您即时(在返回点)实现的接口,例如:

private MethodReturn aMethod(int aParam) {
    …
    return new MethodReturn() {
        @Override
        public Boolean first() { return success; }

        @Override
        public String second() { return msg; }
    };
}
Run Code Online (Sandbox Code Playgroud)