Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/rest/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从单个Java方法返回多个值_Java_Return Type - Fatal编程技术网

从单个Java方法返回多个值

从单个Java方法返回多个值,java,return-type,Java,Return Type,以下是场景: Java方法public\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu submitData(数据)的 我可以想出三种方法 方法1: 返回一个可序列化的对象,其中包含确认号和返回代码作为实例字段 public class Foo { private String confirmationNumber; private ReturnC

以下是场景:

Java方法
public\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu submitData(数据)

我可以想出三种方法

方法1:

返回一个可序列化的对象,其中包含确认号和返回代码作为实例字段

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:

将返回类型设为字符串,并将返回确认号设为字符串,对于任何错误的返回代码,将抛出选中的异常。这是一种经过尝试和测试的方法,它肯定会工作,但是如果有额外的参数返回给调用方,不管响应是成功还是失败,该怎么办?或者如果成功有多个返回码(例如,ReturnCode.OK\u写入到\u DB,ReturnCode.OK\u排队等)


我想知道在这种情况下是否有最佳实践可以遵循?

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


方法1更接近于Haskell方法,Haskell有办法克服您提到的限制(例如幻象类型),但对于Java,只需坚持使用异常,这是祖先所希望的方式。

我将推荐一种方法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);
        }
    }
}
更新


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

“坏”案例是否被视为错误?在Java中,习惯用法是不必检查成功代码(如在C中)以明确标准大小写并使用异常进行错误处理。@chrylis是的,坏大小写意味着无论出于何种原因都无法处理数据。EJB服务的使用者是一个C应用程序,通信通过一个web服务进行。你认为这就是为什么他们要求一个成功代码,即使一个非空的确认号应该是成功的证明吗?我会选择一个选中的例外。保持预期的成功路径尽可能清晰易读。@bez这很可能。在这种情况下,包装器代码应该负责在习语之间进行翻译。@chrylis您的意思是,如果我使用选项3,web服务负责将响应转换为对客户端C应用程序有意义的内容?我在问题中更新了方法3。如果有更多的参数返回天气成功或失败,这将如何工作?@bez在这种情况下,我将结合方法1和方法3。使用方法1中的类,但是如果返回代码是错误,而不是返回它,则将其包装在异常中并抛出它。这样,返回值总是成功的,但是您仍然可以处理失败
尝试{Foo goodFoo=getFoo();}catch(BadFooException e){Foo badFoo=e.getFoo();}
但是如果在这两种情况下都有多个参数要返回,并且如果有多个返回代码与成功关联,该怎么办?请参阅相关更新的方法3。@bez,如果有多个元素也与成功案例相关,我建议您开发一个自定义的
结果
对象。服务将构建此对象并设置必要的属性,如成功|失败标志、错误代码和其他。类似于问题中的方法1?