【问题标题】:Why cannot I catch the exception thrown in nested catch clause using 'outer' catch?为什么我不能使用“外部”捕获捕获嵌套捕获子句中抛出的异常?
【发布时间】:2013-12-23 20:03:31
【问题描述】:

在下面的示例中,您可以看到使用外部 catch 子句无法捕获 IOException(名为 FOURTH)异常。这是为什么? 我知道如果在嵌套的 try 块中抛出异常,可以使用外部捕获来捕获异常。 如果将 b 静态变量值更改为 false 则可以看到。

但是为什么我们不能使用外部 catch 捕获嵌套 catch 子句中抛出的异常呢?

import java.io.*;

public class Exceptions {

    static boolean b = true;

    public static void main(String[] args){
        try {
            exceptions(b);
        } catch (Exception e) {
            System.out.println(e  + " is handled by main().");
        }       
    }

    static void exceptions(boolean b) throws Exception{
        try{
            if(b) throw new FileNotFoundException("FIRST");
            try{
                throw new IOException("SECOND");
            }
            catch(FileNotFoundException e){
                System.out.println("This will never been printed out.");
            }
        }
        catch(FileNotFoundException e){
            System.out.println(e + " is handled by exceptions().");
            try{
                throw new FileNotFoundException("THIRD");        
            }
            catch(FileNotFoundException fe){            
                System.out.println(fe + " is handled by exceptions() - nested.");
            }
            try{
                throw new IOException("FOURTH");
            }
            finally{}
        }
        catch(Exception e){
            System.out.println(e + " is handled by exceptions().");
        }
    }
}

如果 b = true 的输出:

java.io.FileNotFoundException:FIRST 由 exceptions() 处理。 java.io.FileNotFoundException: THIRD 由 exceptions() 处理 - 嵌套。 java.io.IOException: FOURTH 由 main() 处理。

如果 b = false 的输出:

java.io.IOException: SECOND 由 exceptions() 处理。

【问题讨论】:

  • 如果在“FOURTH”异常之后删除 finally{} 会发生什么?
  • 确实如此。找到最后一个 try/catch 语句。
  • 你不是从try 块中扔掉它,而是从catch 块中扔掉它。
  • 当你运行这个时会发生什么,异常是否完全未被捕获?
  • @Chthonic Project 如果您最终删除{},那么它将无法编译

标签: java exception nested try-catch


【解决方案1】:

但是为什么我们不能使用外部 catch 捕获嵌套 catch 子句中抛出的异常呢?

你可以。问题是您的最后一个 catch(Exception e) 处于 same 嵌套级别,这就是为什么它没有捕获在前一个 catch 块中抛出的异常。

尝试像这样嵌套你的 try/catch 块

static void exceptions(boolean b) {
    try {
        try {
            if (b) throw new FileNotFoundException("FIRST");
            try {
                throw new IOException("SECOND");
            } catch (FileNotFoundException e) {
                System.out.println("This will never been printed out.");
            }
        } catch (FileNotFoundException e) {
            System.out.println(e + " is handled by exceptions().");
            try {
                throw new FileNotFoundException("THIRD");
            } catch (FileNotFoundException fe) {
                System.out.println(fe + " is handled by exceptions() - nested.");
            }
            // will be caught by the nested try/catch at the end.
            throw new IOException("FOURTH");
        }
    } catch (Exception e) {
        System.out.println(e + " is handled by exceptions().");
    }
}

【讨论】:

  • @Chris 在这种情况下 AFAICS 没有问题。
  • 感谢您的示例,它很棒。但是,我知道我们可以使用外部 catch 捕获嵌套 try 块中抛出的异常。这就是当 b = false 时我的异常 SECOND 发生的情况。我的问题是为什么当 b = true 时我们不能做同样的事情? (嵌套 catch 中抛出的 IOexception FOURTH 不能被外部 catch 捕获?)为什么你们说我的 catch(Exception e) 子句与抛出的 IOException FOURTH 处于同一级别(显然在另一个 try 块内)?谢谢
  • @LazLondon catch(FNFEtrycatch(Exception相同 在我的示例中,try { try { 是不同的
  • 是的,我知道这个 Peter,我的 catch(FNFE) 和 catch(Exception) 处于同一级别..但是我的第四个异常更深 1 级...(在另一个 try 块内)抱歉如果我很烦人,只是想了解为什么使用我的代码 sn-p 无法捕获它。
  • @LazLondon 正确,也不应该。 catch(Exception e) 用于第一个 try { something } 块,它不会包裹任何 catch 块,因为它处于同一级别,因此它不会尝试/捕获任何抛出在 catch 块中的东西。
【解决方案2】:

你的结构是这样的

try {
 //operation
}
catch (Exce 1){ //catch 1
   // throw IO
}
catch(Exce 2){ //catch 2
   // print error
}

这里catch1和catch2是同级的,catch1抛出的异常不会到达catch2。

因此,您的 IOE 将被退回给调用者。如果您想在方法中处理异常,请按照以下内容进行操作

try{

    try {
     //operation
    }
    catch (Exce 1){ //catch 1
       // throw IO
    }
    catch(Exce 2){ //catch 2
       // print error
    }

}
catch(Exce 3) {
  // your IO will be caught here 
}

【讨论】:

  • 首先,感谢您的示例。但正如我之前所说,我知道我们可以使用外部 catch 捕获嵌套 try 块中抛出的异常。这就是当 b = false 时我的异常 SECOND 发生的情况。我的问题是为什么当 b = true 时我们不能做同样的事情? (嵌套 catch 中抛出的 IOexception FOURTH 不能被外部 catch 捕获?)为什么你们说我的catch(Exception e) 子句与抛出的 IOException FOURTH 处于同一级别(这显然在另一个 try 块内)?谢谢
猜你喜欢
  • 1970-01-01
  • 2011-09-21
  • 1970-01-01
  • 1970-01-01
  • 2020-07-31
  • 2014-11-24
  • 2011-12-07
  • 2021-03-16
  • 1970-01-01
相关资源
最近更新 更多