【问题标题】:Return an arrayList as message in custom exception in JAVA在 JAVA 中的自定义异常中将 arrayList 作为消息返回
【发布时间】:2021-08-30 15:13:03
【问题描述】:

我需要在抛出异常时输出List<String>。一旦抛出异常,我希望程序停止执行。 为了清楚起见,我的代码有以下两个功能:

       List<String> exceptions = new ArrayList<>();
    
        public Boolean validation(Obj obj){
           if(condition1){ exceptions.add("exception1");}
           if(condition2){ exceptions.add("exception2");}
              .
              .
              .
           if(exceptions.size() > 0) return false;
           else return true;
        }
    
        public Obj getValidResponse(Obj obj){
           if(validation(obj)){ return obj;}
           else{ throw new CustomException(exceptions);}  //on this line, the program should return the List<String> of all the exceptions stored. 
        }

每当我抛出异常时,列表都会在我不想要的技术异常消息之后打印。 此外,我无法在 throw 语句中找到使用 customException 中实现的getMessage() 函数返回的方法,因为它给出了Expected throwable type 错误。

我的自定义异常类看起来像:

public class CustomException extends RuntimeException{
    public CustomException(List<String> s) {
        super(String.valueOf(s));
    }
}

我对此很陌生,任何形式的帮助都将不胜感激。 :)

【问题讨论】:

  • 嗨,我不确定我是否理解正确,但似乎您想在抛出异常时向用户显示多个错误消息,即所有可能失败的验证消息的列表。如果是这种情况,您可以创建一个自定义对象,当抛出异常时您的异常会返回该对象。在该对象中,您可以有一个错误消息列表。
  • 是的。我真正想要的是;每当函数'validation'返回false时,它应该抛出一个看起来像[“exception1”,“exception3”,“exceptionX”...]的异常。程序将终止。关于您的建议,我应该如何创建自定义对象?你能详细说明一下吗?谢谢
  • 异常类必须扩展 Throwable,通常是 Exception 或 RuntimeException,而您的 CustomException 类似乎不是。请使用 CustomException 类的代码更新您的问题。
  • 嗨@whbogado,我添加了我的CustomException。这个问题是,我仍然得到类似的结果 - 线程“main”中的异常 CustomException: ["exception1", "exception2", ....] 。有没有办法避免这种情况,只返回列表?

标签: java exception try-catch throws


【解决方案1】:

您可以通过从 RuntimeException 子类化来做到这一点(使用正确的名称和字段以使异常具有自我描述性):

public class CustomException extends RuntimeException {

    private List<String> myStrings;

    public CustomException(List<String> s) {
        this.myString = s;
    }

    public List<String> getMyStrings() {
        return myStrings;
    }

    public String getMessage() {
        return String.join(",", myStrings);
    }
}

Java 只能抛出Throwables,不能抛出其他对象。这与其他编程语言不同。用于字符串表示的getMessage 方法总是返回String。当您需要返回真实列表的不同行为时,您必须使用自己的拦截器 / 故障屏障直接读取字符串列表并应用适当的处理。

当您需要字符串列表为List&lt;String&gt; 时,您能否更准确一些。看来您正在使用一些处理程序代码,不仅对异常的字符串消息感兴趣。在您的代码中,您似乎正在尝试返回Obj。如果失败,您的想法是返回错误列表吗?这不是那样工作的。如果你抛出一些东西,那么这将引发一个异常并且什么都不返回。这是一个不同的程序流程。如果你想返回错误列表,你也可以创建一个特殊的

public class StatusResult {

    private boolean error;
    
    private Obj sucessObj;
   
    private List<String> errorMsgs;

// add constructor and getters here ...
}

但是这种成功/错误处理不像 Java 那样。

【讨论】:

  • 谢谢@k_o_,但我应该如何在throw 语句中使用getMyStrings() 函数?如果我只使用throw new CustomException(exceptions),它会返回类似这样的东西——Exception in thread "main" CustomException:["exc1", "exc4"]——这是我不想要的。
  • Exception in thread ... 听起来像是由 Java 创建的自动堆栈跟踪消息。我假设您在某处捕获异常并处理它以调用getMyStrings。当打印堆栈跟踪或将异常传递给记录器时,Java 正在使用getMessage 方法。我使用的构造函数只是加入传递列表,这是getMessage 使用的。您也可以直接覆盖getMessage 以获得更好的格式。在 Java 中只能抛出 Throwables,这在其他编程语言中是不同的。
  • 查看我的更新答案。我猜你的目标还不清楚。
【解决方案2】:
import java.util.ArrayList;
import java.util.List;
public class CustomException extends Exception{
    private List<String> exceptions;
    public CustomException(List<String> exp) {
        this.exceptions = exp;
    }   
    public List<String> getExceptions(){
        return exceptions;
    }
    public static void main(String[] args) {
    
        try {
            boolean result = getValidResponse();
        }catch(CustomException e) {
            List<String> msgs = e.getExceptions();
            for(String ss:msgs) {
                System.out.println(ss);
            }
        }
    }   
    static List<String> exps = new ArrayList<String>(); 
    public static boolean validation(boolean error){
        boolean result = false;
        if(error) {         
            exps.add("Error msg 1");
            exps.add("Error msg 2");            
        }else{
            result =  true;
        }        
        return result;
    }   
    public static boolean getValidResponse() throws CustomException{
        boolean r = false;
        validation(true);
        if(exps.size()>0) {
            throw new CustomException(exps);
        }
        return r;
    }
}

【讨论】:

    【解决方案3】:

    这是针对此类自定义异常类的一种解决方案:

    public class CustomException extends Exception{
    
        private final List<String> errors;
    
        public CustomException(List<String> errors) {
            this.errors = errors;
        }
    
        @Override
        public String getMessage() {
    
            String msg = errors.stream()
                    .collect(Collectors.joining(", ", "[", "]"));
    
            return msg;
        }
    
    }
    

    您可以按如下方式使用它:

    public static void main(String[] args) {
    
        try {
            errorFunc();
        } catch (CustomException exception) {
            System.out.println(exception.getMessage());
        }
    }
    
    public static void errorFunc() throws  CustomException {
    
        List<String> errors = new ArrayList<>();
        errors.add("error#1");
        errors.add("error#2");
        errors.add("error#3");
    
        throw new CustomException(errors);
    }
    

    输出:

    [error#1, error#2, error#3]
    

    但请注意,这通常不是好的做法。一个异常应该代表一个错误而不是多个错误。通常你会创建一个基类,它代表你的异常的一个特殊“类别”。然后,特定错误可以有自己的异常,该异常是从该基本异常派生的。一个例子是 FileNotFoundExcpetion (https://docs.oracle.com/javase/7/docs/api/java/io/FileNotFoundException.html),它是从 IOException 派生的(它又是从 Exception 类派生的)。

    抛出一串多个错误可能表明您的函数正在做不止一件事情(这些事情可能会出错)。

    【讨论】:

    • 我真的不明白为什么这个答案被否决了,它产生了正确的输出。是的,它确实使用了已检查的异常,这可能会受到批评,但是由于 Java 输出异常的方式,使用未检查的异常不会更好。在每种情况下,您都必须使用 try/catch 块并查看:Unchecked Exceptions - The Controversy
    猜你喜欢
    • 2017-07-01
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2014-09-28
    相关资源
    最近更新 更多