ловля исключений jvm - PullRequest
       5

ловля исключений jvm

3 голосов
/ 31 марта 2012

Итак, я недавно написал класс 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 ]

7 голосов
/ 31 марта 2012

строка, в которой написано, что исключение было получено, это строка, из которой исключение было создано, а не от того, где оно было брошено. Я просто интересно, почему это так и предназначено ли это поведение для jvm или нет

Да. Он не только предназначен, но и задокументирован. См. Javadoc для java.lang.Throwable: «В throwable содержится снимок стека выполнения его потока на момент его создания». Если вы не хотите этого, у вас есть возможность позвонить fillInStackTrace() непосредственно перед тем, как его бросить.

1 голос
/ 31 марта 2012

Из JavaDoc для 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(). Если эта информация важна, вы можете выдать новое исключение с оригиналом в качестве аргумента причины.

UPDATE

Чтобы проиллюстрировать, что если вы действительно хотите знать, что исключение также было выдано в foo(), то вы должны сделать это в foo()

void foo() throws Exception
{
    try
    {
        bar();
    }
    catch (Exception e)
    {
        throw new Exception("Some more useful information from foo", e);
    }
}
...