如果catch抛出异常,我该如何处理?
If the catch throws exceptions, how should I handle them?
我有一个简单的编码方案,例如:
class A
{
public static void main(String[] args)
{
try{
//some exception
}
catch(Exception e)
{
//Again some exception
}
finally
{
System.out.println("Finally executed");
}
}
}
我的问题:
- 有没有办法处理catch中的异常?如果是,那怎么办?
- 如果finally块有异常,有什么办法处理吗?
- 或者在 catch 或 finally 块中出现异常只是糟糕的编程习惯吗?
您可以按照以下方式简单地处理它们...
class A
{
public static void main(String excep[])
{
try{
//some exception
}
catch(Exception e)
{
//Again some exception
try {}
catch(Exception e){}
}
finally
{
System.out.println("Finally executed");
try {}
catch(Exception e){}
}
}
}
这通常在 FileStream 关闭示例中完成,如下例所示
FileStream in = new FileStream(f);
finally {
if (input != null) {
try {
in.close();
}catch (IOException exp) {
System.out.println(exp);
}
}
- 异常可以在catch中处理。
- finally 块中有时需要处理异常。
这不是坏习惯,但如果您想以有意义的方式处理异常,请捕获预期的异常。示例如下。
public void test()
{
InputStream stream = null;
try{
// do something
// initialize stream
// again do something
}
catch(ExpectedException e)
{
//Handle the expected exception add a meaningful message here
//If needed new exception (custom exception) can be thrown to where this
// method is called and the new exception should be a meaningful to the called
}
finally
{
if (stream != null)
try{
steam.close();
}catch(Exception e){
//log the error and throw if needed as explained above.
}
}
}
1) 有什么方法可以处理 catch 中的异常吗?如果是,那怎么办? 是
您可以在 catch()
中使用另一个 try catch
块,或者您也可以抛出异常;
try {
// some exception
}
catch (Exception e) {
try {
// Again some exception
// some exception
}
catch (Exception e1) {
// Again some exception
throw new RuntimeException();//throwing a runtime exception, you can throw here your required exception
}
}
2)如果finally块有异常怎么办,有什么办法处理吗? 是
与我讨论问题 (1) 的方式相同。
3) 还是在 catch 或 finally 块中出现异常只是糟糕的编程习惯? 可能是
因为你需要在 catch 块中捕获所有异常,这是更好的方法。但是您可以使用另一个 try catch
块来处理 finally
块中的异常。
Try catch 块中 finally 块的示例代码
finally {
try {
System.out.println("Finally executed");
} catch (Exception final_ex) {
// handle exception
}
}
1 和 2) 是的,您可以通过嵌套 try 块或让异常被抛出(取决于情况需要)来完成这两个操作。
3) 这不是坏习惯,这是不可避免的
有几件事你应该注意。
一个潜在的问题是异常屏蔽。当您从 catch 或 finally 块中抛出异常时,它将取代任何原始异常。如果您有某种 Closeable,例如 InputStream 或 JDBC 对象,您必须在 finally 块中关闭资源,如果您让该异常被抛出,那么您将丢失原始异常,该异常会告诉您实际发生了什么错了。
对于在 finally 块中抛出异常的情况,要考虑的另一件事是您是否希望传播异常。对于 JDBC 示例,一旦事务已经提交,那么如果在关闭连接时抛出异常,则它与业务逻辑无关,这只是一个麻烦。所以这种事情的常见方法是在 finally 块中捕获异常并记录它,但不要重新抛出它。
try-with-resources 功能试图修复异常屏蔽。如果在 try 中抛出异常后,finally 块中抛出异常,则将关闭时的异常添加到原始异常上,您可以通过 Throwable#getSuppressed
方法访问它。
try-with-resources 还提供了一种避免嵌套 try-finally 块的方法,您可以声明多个可关闭对象,它们将按后进先出的顺序关闭。
try-with-resources 抑制关闭时抛出的异常仅在 try 块中抛出异常时才有效,否则关闭时抛出的异常会传播。此行为不同于捕获和记录关闭时抛出的任何内容的旧模式,后者根本不会重新抛出关闭异常。
我有一个简单的编码方案,例如:
class A
{
public static void main(String[] args)
{
try{
//some exception
}
catch(Exception e)
{
//Again some exception
}
finally
{
System.out.println("Finally executed");
}
}
}
我的问题:
- 有没有办法处理catch中的异常?如果是,那怎么办?
- 如果finally块有异常,有什么办法处理吗?
- 或者在 catch 或 finally 块中出现异常只是糟糕的编程习惯吗?
您可以按照以下方式简单地处理它们...
class A
{
public static void main(String excep[])
{
try{
//some exception
}
catch(Exception e)
{
//Again some exception
try {}
catch(Exception e){}
}
finally
{
System.out.println("Finally executed");
try {}
catch(Exception e){}
}
}
}
这通常在 FileStream 关闭示例中完成,如下例所示
FileStream in = new FileStream(f);
finally {
if (input != null) {
try {
in.close();
}catch (IOException exp) {
System.out.println(exp);
}
}
- 异常可以在catch中处理。
- finally 块中有时需要处理异常。
这不是坏习惯,但如果您想以有意义的方式处理异常,请捕获预期的异常。示例如下。
public void test() { InputStream stream = null; try{ // do something // initialize stream // again do something } catch(ExpectedException e) { //Handle the expected exception add a meaningful message here //If needed new exception (custom exception) can be thrown to where this // method is called and the new exception should be a meaningful to the called } finally { if (stream != null) try{ steam.close(); }catch(Exception e){ //log the error and throw if needed as explained above. } }
}
1) 有什么方法可以处理 catch 中的异常吗?如果是,那怎么办? 是
您可以在 catch()
中使用另一个 try catch
块,或者您也可以抛出异常;
try {
// some exception
}
catch (Exception e) {
try {
// Again some exception
// some exception
}
catch (Exception e1) {
// Again some exception
throw new RuntimeException();//throwing a runtime exception, you can throw here your required exception
}
}
2)如果finally块有异常怎么办,有什么办法处理吗? 是 与我讨论问题 (1) 的方式相同。
3) 还是在 catch 或 finally 块中出现异常只是糟糕的编程习惯? 可能是
因为你需要在 catch 块中捕获所有异常,这是更好的方法。但是您可以使用另一个 try catch
块来处理 finally
块中的异常。
Try catch 块中 finally 块的示例代码
finally {
try {
System.out.println("Finally executed");
} catch (Exception final_ex) {
// handle exception
}
}
1 和 2) 是的,您可以通过嵌套 try 块或让异常被抛出(取决于情况需要)来完成这两个操作。
3) 这不是坏习惯,这是不可避免的
有几件事你应该注意。
一个潜在的问题是异常屏蔽。当您从 catch 或 finally 块中抛出异常时,它将取代任何原始异常。如果您有某种 Closeable,例如 InputStream 或 JDBC 对象,您必须在 finally 块中关闭资源,如果您让该异常被抛出,那么您将丢失原始异常,该异常会告诉您实际发生了什么错了。
对于在 finally 块中抛出异常的情况,要考虑的另一件事是您是否希望传播异常。对于 JDBC 示例,一旦事务已经提交,那么如果在关闭连接时抛出异常,则它与业务逻辑无关,这只是一个麻烦。所以这种事情的常见方法是在 finally 块中捕获异常并记录它,但不要重新抛出它。
try-with-resources 功能试图修复异常屏蔽。如果在 try 中抛出异常后,finally 块中抛出异常,则将关闭时的异常添加到原始异常上,您可以通过 Throwable#getSuppressed
方法访问它。
try-with-resources 还提供了一种避免嵌套 try-finally 块的方法,您可以声明多个可关闭对象,它们将按后进先出的顺序关闭。
try-with-resources 抑制关闭时抛出的异常仅在 try 块中抛出异常时才有效,否则关闭时抛出的异常会传播。此行为不同于捕获和记录关闭时抛出的任何内容的旧模式,后者根本不会重新抛出关闭异常。