4
class chain_exceptions{
   public static void main(String args[]){
      try
      {
         f1();
      }
      catch(IndexOutOfBoundsException e)
      {
         System.out.println("A");
         throw new NullPointerException(); //Line 0
      }
      catch(NullPointerException e) //Line 1
      {
         System.out.println("B");
         return;
      }
      catch (Exception e)
      {
         System.out.println("C");
      }
      finally
      {
         System.out.println("D");
      }
      System.out.println("E");
   }

   static void f1(){
      System.out.println("Start...");
      throw new IndexOutOfBoundsException( "parameter" );
   }
}

我希望第 1 行捕获从第 0 行抛出的 NullPointerException,但它没有发生。

但为什么会这样?

当定义了另一个 catch 块时,为什么 Line1 的 NPE 处理程序不能捕获它?

是因为“抛出”直接进入 main() 方法吗?

4

11 回答 11

9

Catch{ . . . }块与try{ . . . }块相关联。块只能捕获从 try 块抛出的异常catch。第一个 catch 块之后的其他 catch 块与 try 块无关,因此当您抛出异常时,它们不会被捕获。或者main()不捕获异常。

每个 catch 块的一种 this 会做你想做的事情。

try{
  try
  {
     f1();
  }
  catch(IndexOutOfBoundsException e)
  {
     System.out.println("A");
     throw new NullPointerException(); //Line 0
  }
}
catch(NullPointerException e) //Line 1
{
     System.out.println("B");
     return;
}
于 2013-09-04T07:51:25.670 回答
3

catch 块仅用于 try 块。他们不会从其他 catch 块中捕获异常。

于 2013-09-04T07:51:18.377 回答
3

catchtry { ... }语句只捕获从块中抛出的异常。

NullPointerException是从块中抛出的,catch { ... }而不是从块中抛出的try { ... }

要捕获从块中抛出的异常,catch您需要在其中放置另一个 try块。在外面,包装原件try...catch也可以。

于 2013-09-04T07:51:21.733 回答
2

第二个catch不会从第一个catch块中捕获异常。您必须在第一个块内(或您已经拥有的整个块try-catch )添加另一个,以使其按预期运行。catchtry-catch

于 2013-09-04T07:51:34.423 回答
2

由于 java 7 您可以使用下面的代码或其他选项是嵌套 try catch 语句,因此 java 中没有其他选项

try { 
 ...
} catch( indexoutofboundsexception| nullpointerexception ex ) { 
  logger.log(ex);
  throw ex;
}
于 2013-09-04T07:52:13.433 回答
1

您的catch子句仅捕获由f1(). 它们不会调用catch在同一 try-catch-finally 构造的其他子句中抛出的异常。

于 2013-09-04T07:51:26.013 回答
1

因为f1()抛出IndexOutOfBoundsException

try
      {
         f1(); //throws IndexOutOfBoundsException
      }
      catch(IndexOutOfBoundsException e) //gets caught here immediately and does not check other catch blocks
      {
         System.out.println("A");
         throw new NullPointerException(); //Line 0
      }
于 2013-09-04T07:51:26.263 回答
1

简短的回答:是的,throw将直接将异常抛出到 main 方法。

通常,一旦一个catch块被执行,它的行为就像一个else if,也就是说,它不会考虑其他的选择。

于 2013-09-04T07:51:28.300 回答
1

不,它没有被捕获的原因是它不在链接到 catch 块的 try 块中。如果您还想捕获该异常,则必须将 throw 包装在一个新的 try/catch 组中。你为什么要这样做,对我来说是个谜。

顺便说一句,您还可以做什么:

catch (IndexOutOfBoundsException|NullPointerException e)

这也将允许您对多种类型的异常使用相同的 catch 块。

于 2013-09-04T07:52:02.577 回答
1

您的期望不正确:

catch块与块相关联try。因此,一旦在 内部引发异常try,它就会离开该范围。现在您在之外的范围内try,这意味着您不再位于任何try/catch块中。这里抛出的任何异常(当你重新- 时throw)都不会被任何东西捕获,是的,从main.

于 2013-09-04T07:52:18.140 回答
1

你不能catch从另一个块中例外catch,因为你可能需要在你的第一个 catch 块中做这样的事情

System.out.println("A");
try{
     throw new NullPointerException(); //Line 0
}    
catch(NullPointerException e) //Line 1
{      
     System.out.println("B");
     return;
}
于 2013-09-04T07:52:52.003 回答