从单个Java方法返回多个值

时间:2017-09-17 19:27:29

标签: java return-type

以下是该方案:

Java方法public _____ submitData(Data data)的调用者在成功处理提交的数据时需要确认号,如果没有,则返回返回码。

我可以想到三种方法。

方法1:

返回包含确认号和ReturnCode的可序列化对象作为实例字段。

public class Foo {

    private String confirmationNumber;

    private ReturnCode returnCode;

    public Foo(ReturnCode returnCode) {
        this(null, returnCode);
    }

    public Foo(String confirmationNumber, ReturnCode returnCode) {
        if ((returnCode == ReturnCode.OK && confirmationNumber == null)
                || (returnCode != ReturnCode.OK && confirmationNumber != null)) {
            throw new IllegalArgumentException("Bad combination of parameters.");
        }
        this.confirmationNumber = confirmationNumber;
        this.returnCode = returnCode;
    }

    public enum ReturnCode {

        OK, ERROR1, ERROR2, ERROR3, ERROR4, ERROR5;

    }

}

此方法的问题是强制对象的正确实例化。调用代码需要知道对象创建的规则(例如,可以使用ReturnCode.OK和null确认号来实例化Foo。)

方法2:

返回一个接口或抽象类型,并根据成功或失败处理方法中的数据创建Foo的变体,如下例所示:

public abstract class Foo {

    public abstract String getConfirmationCode();

    public abstract ReturnCode getReturnCode();

}


public class GoodFoo extends Foo {

    private final String confirmationCode;

    private final ReturnCode returnCode = ReturnCode.OK;

    public GoodFoo(String confirmationCode) {
        this.confirmationCode = confirmationCode;
    }

    @Override
    public ReturnCode getReturnCode() {
        return returnCode;
    }

    @Override
    public String getConfirmationCode() {
        return confirmationCode;
    }

}


public class BadFoo extends Foo {

    private final ReturnCode returnCode;

    public BadFoo(ReturnCode returnCode) {
        if (returnCode == ReturnCode.OK){
            throw new IllegalArgumentException("BadFoo cannot have a good return code");
        }

        this.returnCode = returnCode;

    }

    @Override
    public ReturnCode getReturnCode() {
        return returnCode;
    }

    @Override
    public String getConfirmationCode() {
        return null;
    }

方法3:

使返回类型为String并将确认号返回为String,对于任何错误的返回码,抛出已检查的异常。这是一种经过试验和测试的方法,它肯定会起作用但是如果有其他参数返回给调用者,无论响应是成功还是失败,该怎么办?或者,如果有多个成功的返回码(例如,ReturnCode.OK_WRITTEN_TO_DB,ReturnCode.OK_QUEUED等)

我想知道在这种情况下是否有最佳做法?

2 个答案:

答案 0 :(得分:1)

方法3是Java方式。返回值并将失败代码作为异常抛出。

方法1更接近Haskell方式,Haskell有办法克服你提到的限制(例如幻像类型),但对于Java,只需坚持异常,就像祖先所期望的那样。

答案 1 :(得分:0)

我会推荐方法4 。如果成功,则返回确认号,但如果有任何错误,则抛出自定义异常。使客户端负责处理异常并在发生故障时从自定义异常对象中检索代码。

以下是一个例子:

public class InvalidDataException extends Exception {

    public Integer errorCode;
    public InvalidDataException (Integer errorCode) {
        this.errorCode = errorCode;
    }
}

public class ServiceClass {
    public String submitData(Data data) {
        //Do processing
        if(error1) {
            throw new InvalidDataException(100);
        }
        else if(error1) {
            throw new InvalidDataException(200);
        }
        return UUID.randomUUID().toString(); //conf number
    }
}

public class ClientClass {
    public static void main(String[] args) {
        String confNum = "";       
        Data data = new Data();
        //Build data
        ServiceClass sc = new ServiceClass();
        try {
           confNum = sc.submitData(data);
        }
        catch(InvalidDataException e) {
            System.out.println("An error occurred with the code " + e.errorCode);
        }
    }
}

<强>更新

如果有多个元素也与成功案例相关联,我建议您开发一个自定义Result对象。该服务将构建此对象并设置必要的属性,例如success |失败标志,错误代码等。该方法的返回值将是此Result对象。客户端必须从Result对象获取必要的信息。