在同一catch子句中,我能捕获多个Java异常吗?

Can I catch multiple Java exceptions in the same catch clause?

在爪哇,我想做这样的事情:

1
2
3
4
5
6
try {
    ...    
} catch (/* code to catch IllegalArgumentException, SecurityException,
            IllegalAccessException, and NoSuchFieldException at the same time */
) {
   someCode();
}

……代替:

1
2
3
4
5
6
7
8
9
10
11
try {
    ...    
} catch (IllegalArgumentException e) {
    someCode();
} catch (SecurityException e) {
    someCode();
} catch (IllegalAccessException e) {
    someCode();
} catch (NoSuchFieldException e) {
    someCode();
}

有什么办法吗?


自从Java 7以来,这是可能的。多catch块的语法为:

1
2
3
4
5
try {
  ...
} catch (IOException | SQLException ex) {
  ...
}

不过,请记住,如果所有异常都属于同一个类层次结构,则可以简单地捕获该基本异常类型。

还要注意,如果exceptionb是直接或间接从exceptiona继承的,则不能在同一块中同时捕获exceptiona和exceptionb。编译器将投诉:

1
2
Alternatives in a multi-catch statement cannot be related by subclassing
  Alternative ExceptionB is a subclass of alternative ExceptionA


不完全是在Java 7之前,但是,我会做这样的事情:

Java 6与以前

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
try {
  //.....
} catch (Exception exc) {
  if (exc instanceof IllegalArgumentException || exc instanceof SecurityException ||
     exc instanceof IllegalAccessException || exc instanceof NoSuchFieldException ) {

     someCode();

  } else if (exc instanceof RuntimeException) {
     throw (RuntimeException) exc;    

  } else {
    throw new RuntimeException(exc);
  }

}

爪哇7

1
2
3
4
5
6
try {
  //.....
} catch ( IllegalArgumentException | SecurityException |
         IllegalAccessException |NoSuchFieldException exc) {
  someCode();
}


在Java 7中,可以定义多个catch子句,例如:

1
2
3
4

不,每个客户一个。

只要在所有情况下都采取相同的操作,就可以捕获超类,如java.lang.exception。

1
2
3
4
5
try {
    // some code
} catch(Exception e) { //All exceptions are caught here as all are inheriting java.lang.Exception
    e.printStackTrace();
}

但这可能不是最佳实践。只有当您有实际处理异常的策略时,才应该捕获异常——而日志记录和重新执行并不是"处理它"。如果您没有纠正措施,最好将其添加到方法签名中,并让它冒泡到能够处理这种情况的人身上。


如果存在异常层次结构,则可以使用基类捕获异常的所有子类。在退化的情况下,您可以捕获所有Java异常:

1
2
3
4
5
try {
   ...
} catch (Exception e) {
   someCode();
}

在更常见的情况下,如果repositoryException是基类,而pathNotFoundException是派生类,则:

1
2
3
4
5
6
7
try {
   ...
} catch (RepositoryException re) {
   someCode();
} catch (Exception e) {
   someCode();
}

上述代码将捕获一种异常处理的RepositoryException和PathNotFoundException,而所有其他异常都集中在一起。从Java 7开始,就像@ OsCARRYZ的答案一样:

1
2
3
4
5
try {
  ...
} catch( IOException | SQLException ex ) {
  ...
}


对Java 6(即Android)的USER44322的回答的一个清洁器(但不是冗长的,也许不是首选的)将捕获所有的EDCOX1,0,s,并重新抛出EDCOX1,1,s。如果您计划在堆栈上进一步捕获其他类型的异常(如果您不重新抛出它们),这将不起作用,但将有效地捕获所有CH。检查异常。

例如:

1
2
3
4
5
6
7
8
9
10
try {
    // CODE THAT THROWS EXCEPTION
} catch (Exception e) {
    if (e instanceof RuntimeException) {
        // this exception was not expected, so re-throw it
        throw e;
    } else {
        // YOUR CODE FOR ALL CHECKED EXCEPTIONS
    }
}

也就是说,为了详细起见,最好设置一个布尔值或其他变量,并基于该变量在try-catch块之后执行一些代码。


在7岁之前的儿童中,如何:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  Boolean   caught = true;
  Exception e;
  try {
     ...
     caught = false;
  } catch (TransformerException te) {
     e = te;
  } catch (SocketException se) {
     e = se;
  } catch (IOException ie) {
     e = ie;
  }
  if (caught) {
     someCode(); // You can reference Exception e here.
  }


对。下面是使用管道分隔符的方法,

1
2
3
4
5
6
7
8
try
{
    .......
}    
catch
{
    catch(IllegalArgumentException | SecurityException | IllegalAccessException | NoSuchFieldException e)
}


捕获恰好是异常层次结构中父类的异常。这当然是不好的做法。在您的例子中,常见的父异常恰好是异常类,捕获异常实例的任何异常实际上是不好的做法-异常(如nullpointerException)通常是编程错误,通常应通过检查空值来解决。