我需要一个非静态实例方法来返回多个值。为了一个简单的例子,让我们说这些是boolean success
和Object 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... }
我可能错过了更多的可能性吗?任何人都可以评论每个人的利弊(理想情况下,在大多数情况下最好使用哪个)?
答案 0 :(得分:7)
一般情况下,我会根据具体情况选择第4个地图或地图,但如果您需要返回多个不相关的值,我认为您有严重的设计问题(请检查https://en.wikipedia.org/wiki/Single_responsibility_principle)< / p>
在特定情况下(在您的评论之后),我肯定会使用所有必填字段对响应进行第4次建模。也可以使用ResponseSuccessful和ResponseFailure进行子类型化。
答案 1 :(得分:4)
通过回调,您甚至可以返回多个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));
评论您的解决方案:
Pair<T,U>
或Tuple2<T,U>
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)
在我的程序中,如果返回的对象在逻辑上与某些内容相关,则可能需要拥有自己的类:boolean
和String
可能是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
}
您可以根据需要为调用者填写尽可能多的不同值。