在Java中,我想做这样的事情:
try {
...
} catch (/* code to catch IllegalArgumentException, SecurityException,
IllegalAccessException, and NoSuchFieldException at the same time */) {
someCode();
}
...代替:
try {
...
} catch (IllegalArgumentException e) {
someCode();
} catch (SecurityException e) {
someCode();
} catch (IllegalAccessException e) {
someCode();
} catch (NoSuchFieldException e) {
someCode();
}
有没有办法做到这一点?
这是可能的since Java 7。多捕获块的语法是:
try {
...
} catch (IllegalArgumentException | SecurityException | IllegalAccessException |
NoSuchFieldException e) {
someCode();
}
但请记住,如果所有异常都属于同一个类层次结构,您可以简单地捕获该基本异常类型。
另请注意,如果 ExceptionB
直接或间接地从 ExceptionA
继承,则不能在同一块中同时捕获 ExceptionA
和 ExceptionB
。编译器会抱怨:
Alternatives in a multi-catch statement cannot be related by subclassing
Alternative ExceptionB is a subclass of alternative ExceptionA
对此的修复是只在异常列表中包含祖先异常,因为它也会捕获后代类型的异常。
不完全是在 Java 7 之前,但是,我会做这样的事情:
Java 6 及之前版本
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
try {
//.....
} catch ( IllegalArgumentException | SecurityException |
IllegalAccessException |NoSuchFieldException exc) {
someCode();
}
exc.getCause()
获得原始异常。作为旁注,Robert C. Martin(以及其他人)建议使用未经检查的异常(编译器不知道会从那里抛出什么样的异常);请参阅他的书清洁代码中的第7章:错误处理。
throw exc
而不是 throw new RuntimeException(exc)
?
在 Java 7 中,您可以定义多个 catch 子句,例如:
catch (IllegalArgumentException | SecurityException e)
{
...
}
不,在 Java 7 之前,每个客户一个。
只要在所有情况下都采取相同的操作,就可以捕获超类,例如 java.lang.Exception。
try {
// some code
} catch(Exception e) { //All exceptions are caught here as all are inheriting java.lang.Exception
e.printStackTrace();
}
但这可能不是最佳做法。只有当您有实际处理它的策略时,您才应该捕获异常 - 并且记录和重新抛出不是“处理它”。如果您没有纠正措施,最好将其添加到方法签名中,并让它冒泡给可以处理这种情况的人。
使用 JDK 7 及更高版本,您可以执行以下操作:
try {
...
} catch (IllegalArgumentException | SecurityException | IllegalAccessException | NoSuchFieldException e) {
someCode();
}
如果存在异常层次结构,您可以使用基类来捕获异常的所有子类。在退化的情况下,您可以通过以下方式捕获所有 Java 异常:
try {
...
} catch (Exception e) {
someCode();
}
在更常见的情况下,如果 RepositoryException 是基类而 PathNotFoundException 是派生类,则:
try {
...
} catch (RepositoryException re) {
someCode();
} catch (Exception e) {
someCode();
}
上面的代码将捕获 RepositoryException 和 PathNotFoundException 以进行一种异常处理,并将所有其他异常集中在一起。从 Java 7 开始,根据上面@OscarRyz 的回答:
try {
...
} catch( IOException | SQLException ex ) {
...
}
user454322 在 Java 6(即 Android)上的答案的更简洁(但不那么冗长,也许不是首选)替代方法是捕获所有 Exception
并重新抛出 RuntimeException
。如果您计划在堆栈中进一步捕获其他类型的异常(除非您也重新抛出它们),这将不起作用,但会有效地捕获所有 checked 异常。
例如:
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 块之后执行一些代码。
在 pre-7 中如何:
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.
}
caught
的最终控件插入到 finally
块中?
这很简单:
try {
// Your code here.
} catch (IllegalArgumentException | SecurityException | IllegalAccessException |
NoSuchFieldException e) {
// Handle exception here.
}
对于 kotlin,目前还不可能,但他们已经考虑添加它:Source
但是现在,只是一个小技巧:
try {
// code
} catch(ex:Exception) {
when(ex) {
is SomeException,
is AnotherException -> {
// handle
}
else -> throw ex
}
}
在异常层次结构中捕获恰好是父类的异常。 This is of course, bad practice。在您的情况下,常见的父异常恰好是 Exception 类,并且捕获作为 Exception 实例的任何异常确实是不好的做法 - NullPointerException 之类的异常通常是编程错误,通常应该通过检查空值来解决。
不定期副业成功案例分享
bitwise or
(|
) 运算符?为什么不使用逗号或具有更相似含义的运算符logical or
(||
)?