在Java中抛出多个异常

时间:2010-05-26 11:43:25

标签: java exception

有没有办法在java中抛出多个异常?

11 个答案:

答案 0 :(得分:20)

我想您可以创建一个包含已捕获异常列表的异常并抛出该异常,例如:

class AggregateException extends Exception {
    List<Exception> basket;
}

答案 1 :(得分:20)

一种方法可以抛出一些例外。例如:

 public void dosomething() throws IOException, AWTException {
      // ....
 }

这表示该方法最终可以抛出一个这两个异常(以及任何未经检查的异常)。你不能(用Java或任何语言AFAIK)同时抛出两个例外,这没有多大意义。

您还可以抛出嵌套异常,其中包含另一个异常对象。但这几乎不能算作“抛出两个例外”,它只是表示由两个异常对象(通常来自不同层)描述的单个异常情况。

答案 2 :(得分:15)

你不能抛出两个例外。即你做不了类似的事情:

try {
    throw new IllegalArgumentException(), new NullPointerException();
} catch (IllegalArgumentException iae) {
    // ...
} catch (NullPointerException npe) {
    // ...
}

备选方案1:异常A是由异常B

引起的

您可以使用cause-constructor 嵌套例外来执行以下操作:

try {
    Exception ex1 = new NullPointerException();

    // Throw an IllegalArgumentException that "wraps" ex1
    throw new IllegalArgumentException(ex1);
} catch (IllegalArgumentException iae) {
    // handle illegal argument...
    throw iae.getCause(); // throws the cause (the NullPointerException)
}

关于链式例外的好文章:Programming.Guide: Chained Exceptions

备选方案2:使用抑制例外

一个例外可以抑制另一个异常。

try {
    Exception ex1 = new NullPointerException();

    // Throw an IllegalArgumentException that "suppresses" ex1
    IllegalArgumentException ex2 = new IllegalArgumentException();
    ex2.addSuppressed(ex1);
    throw ex2;
} catch (IllegalArgumentException iae) {
    // handle illegal argument...
    ... iae.getSuppressed() ... // get hold of the suppressed exceptions
}

有关抑制例外的好文章:Programming.Guide: Suppressed Exceptions

答案 3 :(得分:6)

抛出多个异常没有意义,因为您不能有多个错误(错误可能有多个原因,但任何时候都不会有多个错误)。

如果您需要跟踪原因,可以链接例外:

} catch (Exception ex) {
    throw new RuntimeException("Exc while trying ...", ex);
}

可通过getCause()获取这些内容。

答案 4 :(得分:5)

我见过一种模式,其中自定义异常在内部存储其他异常(不记得,为什么会这样做),但它就像:

public class ContainerException extends Exception {

  private List<Exception> innerExeptions = new Arrayist<Exception>();

  // some constructors

  public void add(Exception e) {
    innerExceptions.add(e);
  }

  public Collection<Exception> getExceptions() {
    return innerExceptions;
  }
}

它的用法如下:

try {
  // something
} catch (ContainerException ce) {
  ce.add(new RunTimeException("some Message");
  throw ce; // or do something else
}

稍后在代码中,评估容器异常并将其转储到日志文件中。

答案 5 :(得分:3)

您可以抛出多个不同的异常。例如:

if (obj == null)
    throw new NullPointerException();

if (some other case)
    throw new IllegalArgumentException();

if (this == this)
    throw new IOException();

此代码可能会抛出多个不同的异常,但这种情况永远不会同时发生。

答案 6 :(得分:3)

当您处理用户提供的文件的服务器端编译并想要报告错误时,Andreas_D描述的模式绝对有用。

例如,如果资源无法编译,您可能会生成CompilationException。编译可能意味着任何数量的事情。例如,您可以评估最终用户上载的文件内部的文本,解析标记,检查语法错误并确定文件是否有效。最后,该东西要么有效,要么无效,并且您希望返回适当的CompilationException以传播备份调用堆栈。

与Andreas描述的一样,您可以使用add()方法,该方法可以向您的异常添加编译问题。这些问题本身并不一定是例外,但这取决于你。通常有助于坚持单个异常框架,以便您可以在多个位置使用相同的验证逻辑。

无论如何,你想要的是一个CompilationException通过调用堆栈回退,因为它告诉框架该东西没有编译。如果链上的任何人想知道原因,那么他们可以通过调用getCauses()来解决潜在的问题。

从UI角度来看,它也很有用。在返回线路之前,可以正确处理关于Exception的信息,以便您可以向最终用户提供有关编译失败原因的一些信息。

答案 7 :(得分:3)

要在Java中抛出多个异常,首先必须将每个异常压缩为一个自定义异常,然后抛出相同的自定义异常。请检查以下代码段以实现相同的目标。

  public class AggregateException extends Exception {


        public void addException(Exception ex){

        addSuppressed(ex);
        exception = true;
    }
}


public class AnyClass{

    public AggregateException aggExcep = new AggregateException();

    public void whereExceptionOccurs(){
        try{

              //some code
        }catch(Exception e){

              aggExcep.addException(e);
              //throw aggExcep;
        }  
    }
}

使用相同的引用使用相同的引用aggExcep调用方法addException(显然在catch块内)抑制任何异常。 并且最后使用'throw'关键字显式抛出aggExcep。

  

void addSuppressed(Throwable exception)

是Throwable类的预定义方法,它将指定的异常附加到为了传递此异常而被抑制的异常。

答案 8 :(得分:1)

我不确定您是否在询问是否可以一次抛出多个异常,或者我们可以拥有一次代码来处理多个异常。我会尝试回答这两个问题。这是我在StackOverflow上的第一个答案,所以请原谅任何错误。

1)如果你想一次抛出多个例外,我想你不能这样做。考虑类似的情况。当你解决数学问题并达到除以0的点时,在这个时间点只有一个错误,它除以零。所以我猜你只能为给定的语句抛出一个错误。但是,在try catch块中可能存在许多语句,每个语句都可能引发不同的错误。

2)如果你想处理/捕获多个错误,有两种方法可以做到这一点。    i)在Java 7之前:

`try{
     ...
     //some method/action that can be a cause of multiple errors,say X and Y
     ...
 }catch(XException e){
      //Do something if exception X arises.
 }catch(YException e){
      //Do something if exception Y arises.
 }
`

ii)在Java 7之后,您拥有了多捕获功能。

try{
     ...
     //some method/action that can be a cause of multiple errors,say X and Y
     ...
 }catch(XException|YException e){
   // Take action appropriate to both types of exception.
  ...
 }

我相信这会解决你的疑问。 这是我的第一个答案,欢迎所有建议!

答案 9 :(得分:0)

有一种方法可以抛出多个exeptions,但不是一次。例如当编译由于某种原因失败时,您的方法只能抛出一个异常。 如果你必须覆盖不同的机会,你可以声明你抛出所有异常的父类的方法&#34; Exception&#34;。 所以,如果你声明一个方法一般抛出一个异常,这个方法可以抛出任何类型的异常。

例如:

public static void main(String[] args) throws Exception
{
  getClipboard();    // throws an UnsupportedFlavorException
  initIOActivity();  // throw an IOException
}

我不知道你真正需要知道什么,但也许这会有所帮助。 虽然你的帖子^^

已经过了很多时间

问候

答案 10 :(得分:0)

Pi带着aioobe的答案,我所做的是将每个Exception放入列表中,然后将它们作为被抑制的异常添加到新的Exception中,然后抛出新的:

示例:

public JSONObject jsonExceptionExample(int value) throws JSONException {
    //Create Exception List
    List<JSONException> jsonExceptions = new ArrayList<>();
    JSONObject jsonObject = new JSONObject();
    try {

        //Your code that could throw an Exception
        jsonObject.put("key", value);

    } catch (JSONException e){
        //Exception is caught and added to list instead of being thrown
        jsonExceptions.add(e);
    }    
    //Check to see if any Exceptions were caught
    if (jsonExceptions.size() > 0) {
        //Create a new Exception to be the 'parent' Exception
        JSONException jsonException = new JSONException("JSONException(s) thrown");
        //Iterate through your list of errors
        for (JSONException e : jsonExceptions) {
            //Add each one to the parent Exception as 'Suppressed'
            jsonException.addSuppressed(e);
        }
        //Throw your new nested error
        throw jsonException;
    }
    //If no Exceptions were found, resume your code
    return jsonObject;
}

要避免导入(如果您在其他地方还没有列表),也可以抛出新的Exception而不是初始化列表,并使用addSuppressed()`` in the catch block, and later call Exception向其中添加错误.getSuppressed()。length> 0```以确定是否添加了任何内容,但我只喜欢列表的可读性和一般理由,即我不希望在没有实际错误的情况下创建Exception。