Может ли блок catch перехватить Throwable (как ошибка, так и исключение) - PullRequest
9 голосов
/ 21 июля 2011

В одном из моих интервью они спросили меня, можно ли написать Throwable в catch () следующим образом

try{
some code
}
catch(Throwable t)
{
}

Я сказал да. она не выдаст ошибку времени компиляции, но jvm не обработает ее, если возникнет Error (подкласс Throwable), поскольку ошибки - это необратимые условия, которые не могут быть обработаны jvm. чем они дополнительно спросили, чем польза от написания Throwable.

Пожалуйста, дайте мне правильный ответ, мы можем использовать Throwable в улове. если да, то почему.

Ответы [ 5 ]

11 голосов
/ 21 июля 2011

Можно поймать Throwable. И да, вы также поймаете экземпляры java.lang.Error, что является проблемой, например, когда речь идет о. OutOfMemoryError s. Вообще я бы не поймал Throwable х. Если вам нужно, вы должны сделать это на самом высоком месте вашего стека вызовов, например метод main (вы можете захотеть поймать его, записать в журнал и перебросить его).

Я согласен с вашей аргументацией, нет смысла отлавливать события, которые вы не можете обработать (например, OutOfMemoryError). Хороший пост здесь .

2 голосов
/ 21 июля 2011

Да, можно перехватить Throwable.

Будет ли JVM / приложение работать, если вы обнаружите ошибку, зависит от фактической ошибки, которая вызвала, что вызвало и что (есличто-нибудь) ваше приложение делает следующее.

  • В некоторых случаях JVM может работать так плохо, что восстановление невозможно.

  • В некоторых случаях JVM в порядке ... до тех пор, пока вы не делаете определенные вещи.Ошибки загрузки классов являются хорошим примером.Если ваше приложение не пытается использовать класс или зависимые классы, которые вы не смогли загрузить, вы можете продолжить.(На самом деле приложения не предназначены для продолжения без классов, которые не загружаются ... но если бы это было так, это могло бы быть.)

  • В некоторых случаях ядро ​​JVM будет работать нормально, но неуказанный ущерб мог быть нанесен структурам данных приложения и / или его потокам и состоянию вычислений.OOME могут сделать это для вас, особенно если ваше приложение не предназначено для работы с потоками, которые неожиданно умирают.

  • Захват и восстановление из OOMEs проблематичны по другой причине.Хотя завершение текущего вычисления освободит некоторое пространство кучи, есть хороший шанс, что оно не освободит достаточно пространства.Таким образом, вы можете легко попасть в ситуацию, когда ваше приложение многократно выдает и получает много OOME, и не добивается реального прогресса.

Все это означает, что, как правило, плохая идеяпопробуйте восстановить после ошибок.И это соответствует тому, что в javadoc об ошибке написано:

"Ошибка - это подкласс Throwable, который указывает на серьезные проблемы, которые разумное приложение не должно пытаться отследить."

1 голос
/ 23 марта 2018
  • Да, мы можем поймать Throwable, но не рекомендуется ловить Throwable.
  • Catching Throwable также включает Errors, мы не должны отлавливать ошибки, это помогает выявлять проблемы JVM.
0 голосов
/ 21 июля 2011

Catching Throwable будет перехватывать все исключения (включая RuntimeExceptions) и все ошибки. Не рекомендуется перехватывать какие-либо из родительских Throwables (Throwable, Error, Exception или RuntimeException), но это не редкость, если метод выдает слишком много проверенных исключений или выбрасывает Exception.

В некоторых API-интерфейсах нередко документируется метод, который выдает Exception. Это обеспечивает некоторую гибкость за счет контроля. Мне нравится определять новый класс Exception для обработки подобных случаев, но это личное предпочтение.

Следующий простой класс показывает образцы бросаемых типов и соответствующие блоки catch.

public class ThrowableExamples {

    public static void main(String[] args) {
        try {
//          throw new NoSuchMethodException("Exception");
//          throw new Exception("Exception");
//          throw new IllegalStateException("RuntimeException");
//          throw new RuntimeException("RuntimeException");
            throw new NoSuchMethodError("Error");
//          throw new Error("Error");
//          throw new Throwable("Throwable");

        } catch (RuntimeException e) {
            System.out.println("Caught RuntimeException: " +  (e.getMessage().equals("RuntimeException") ? "Expected" : "Unexpected"));

        } catch (Exception e) {
            System.out.println("Caught Exception: " +  (e.getMessage().equals("Exception") ? "Expected" : "Unexpected"));

        } catch (Error e) {
            System.out.println("Caught Error: " +  (e.getMessage().equals("Error") ? "Expected" : "Unexpected"));

        } catch (Throwable e) {
            System.out.println("Caught Throwable: " +  (e.getMessage().equals("Throwable") ? "Expected" : "Unexpected"));
        }
    }
}
0 голосов
/ 21 июля 2011

Throwable может использоваться вместо любого отдельного исключения / ошибки. Однако рекомендуется пройти через ThreadDeadException. Таким образом, вы можете добавить для него дополнительное предложение catch или выполнить фильтрацию по типу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...