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

时间:2016-07-20 12:31:04

标签: java class object methods return

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

解决方案1 ​​

private boolean aMethod(int aParam, Object obj) { ...set obj parameter & return value... }

解决方案2

private Pair<Boolean, Object> aMethod(int aParam) { ...set return pair values... }

解决方案3

private Object obj;
...
private boolean aMethod(int aParam) { ...set obj field & return value... }

解决方案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... }

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

6 个答案:

答案 0 :(得分:7)

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

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

答案 1 :(得分:4)

解决方案5 - 回调

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

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

用法:

aMethod(42, (success, msg) -> {
    if (!success) {
        log.error(msg);
    }
});

此外,您可以按合成返回(n&gt; 2)-tuple ,而无需自定义类 - 例如对于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));

评论您的解决方案:

  • 解决方案1 ​​:修改参数是一种不好的做法,而且,String是不可变的
  • 解决方案2 :常用模式,Pair<T,U>Tuple2<T,U>
  • 解决方案3 :脆弱且气馁,它具有状态丰满(并发等)的所有缺点。
  • 解决方案4 :类似于#2 ,例如class MethodReturn implements Pair<Boolean, String> {}

N.B。:MethodReturn可以是您即时实现的接口(在返回点),例如:

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

        @Override
        public String second() { return msg; }
    };
}

答案 2 :(得分:2)

在我的程序中,如果返回的对象在逻辑上与某些内容相关,则可能需要拥有自己的类:booleanString可能是MessageStatus(编辑:我认为这是你的第四个解决方案。) 举个具体的例子:

public class TurnToken {
/**
 * Number of available Quick Actions
 */
private int quickActionTimes;
/**
 * Number of available Main Actions
 */
private int mainActionTimes;
[...Etcetera with setters and getters]

此类仅由两个整数组成,但逻辑上表示可被视为实体本身

的内容 编辑:我不小心取消了第一部分。如果您的对象不是原始对象,但在逻辑上是相关的,您可以创建一个接口来收集它们:

public interface Adjectivable{
//If they have a commong method even better}

和你的方法

public List<Adjectivable> myMultiReturningMethod{
    List<Adjectivable> theStuffToReturn = new ArrayList<>();
    Etcetera...
}

答案 3 :(得分:2)

解决方案1不起作用,因为java中的字符串是不可变的,

解决方案3您无法始终应用,因为您在实例中保存结果,只要您需要结果,您可能也无法从该实例运行您的方法。

这样我们就得到了非常相似的解决方案2和4。在这两种情况下,您都会返回自定义类中包含的结果。如果您认为Pair对您来说足够了,我会说,使用它,并使用解决方案2。

答案 4 :(得分:1)

如果结果已修复,您可以在此使用枚举。

public Enum Status {

     OK("OK"),
     CREATED("Created"),
     ACCEPTED("Accepted"),
     NO_CONTENT("No Content"),
     FORBIDDEN("Forbidden"),
     NOT_FOUND("Not Found");

     private final String reason;

     Status(final String reasonPhrase) {
        this.reason = reasonPhrase;
    }
}

 private Status aMethod(int aParam) {
  ................
  return Status.OK;
 }

答案 5 :(得分:-2)

使用

Object[] aMethod(){ 

//Create and fill an array of object and return it

}

您可以根据需要为调用者填写尽可能多的不同值。