jvm异常捕获

时间:2012-03-31 08:53:18

标签: java debugging exception-handling jvm

所以我最近编写了一个扩展异常的java类,并使用此类的实例来检查案例并在发生错误时抛出自身。我发现当main的调用者捕获到这个异常时,它所引发异常的行是从创建异常的行开始,而不是从抛出它的位置开始。我只是想知道为什么会这样,以及它是否是jvm的预期行为,因为这不是抛出异常的常用方法。如果它是预期的行为,那么这是什么理由,因为看起来抛出异常的行号会更有用(并且可能更容易跟踪堆栈)。示例案例遵循预期的行为和意外行为。


普通例外投掷:

1  public class Test
2  {
3   public static void main(String ... args) throws Throwable
4   {
5       switch(5)
6       {
7           case 1: throw new Exception("Exception");
8           case 2: throw new Exception("Exception");
9           case 3: throw new Exception("Exception");
10          case 4: throw new Exception("Exception");
11          case 5: throw new Exception("Exception");
12      }
13  }
14 }

输出:

Exception in thread "main" java.lang.Exception: Exception
    at Test.main(Test.java:11)

我的方法(简化):

1  public class Test
2  {
3   public static void main(String ... args) throws Throwable
4   {
5       Exception e = new Exception("Exception");
6       switch(5)
7       {
8           case 1: throw e;
9           case 2: throw e;
10          case 3: throw e;
11          case 4: throw e;
12          case 5: throw e;
13      }
14  }
15 }

输出:

Exception in thread "main" java.lang.Exception: Exception
    at Test.main(Test.java:5)

2 个答案:

答案 0 :(得分:7)

  

它说的异常被抛出的线是从哪里开始的   异常是创建的,而不是从它被抛出的位置。我只是   想知道为什么这是,以及它是否是jvm的预期行为   <或者

是。它不仅是有意的,而且是有记录的。请参阅Javadoc以获取java.lang.Throwable:&#39;一个throwable包含其创建时其线程的执行堆栈的快照。&#39;如果您不想这样,您可以在投掷之前调用fillInStackTrace()

答案 1 :(得分:1)

来自JavaDoc for Throwable

  

通常,这是创建此throwable的点   抛出。

这有点模棱两可,但99%的时候会在抛出异常时创建异常。我想当你考虑重新抛出异常时,从创建点创建堆栈跟踪更有意义,例如:

void bar() throws Exception
{
    throw Exception();
}

void foo() throws Exception
{
    try
    {
        bar();
    }
    catch (Exception e)
    {
        throw e;
    }
}

public static void main(String[] args)
{
   foo();
}

知道在bar()中创建异常比知道它在foo()中被重新抛出更有用。如果此信息很重要,您可以抛出一个新的异常,并将原始参数作为原因参数。

<强>更新

为了说明一下,如果您真的想知道foo()中引发了异常,那么您可以在foo()

中执行此操作
void foo() throws Exception
{
    try
    {
        bar();
    }
    catch (Exception e)
    {
        throw new Exception("Some more useful information from foo", e);
    }
}