Когда следует использовать Throwable вместо нового исключения? - PullRequest
39 голосов
/ 31 января 2009

Дано: Throwable - суперкласс Exception.

Когда я читаю тексты при написании ваших собственных «исключений», я вижу примеры использования Throwable в блоке catch, а другие тексты показывают, что new Exception() используется в блоке catch. Мне еще предстоит увидеть объяснение того, когда следует использовать каждый из них.

У меня такой вопрос: когда следует использовать Throwable и когда следует использовать new Exception()

Внутри блока catch или else введите:

throw throwable;

или

throw new Exception();

Ответы [ 11 ]

37 голосов
/ 31 января 2009

Всегда бросайте Exception (никогда не Throwable). Обычно вы тоже не ловите Throwable, но можете. Throwable - это суперкласс для Exception и Error, поэтому вы бы поймали Throwable, если бы вы хотели не только поймать Exception с, но Error с, вот в чем смысл. Дело в том, что Error s - это, как правило, вещи, которые обычное приложение не может и не должно отлавливать, поэтому просто используйте Exception, если у вас нет особых причин использовать Throwable.

13 голосов
/ 31 января 2009

(из комментариев) Проблема, которая подняла это, состоит в том, что Мне нужно передать «исключение» кусок кода, который строит сотрудник если коллекция не создается.

В этом случае вы можете выдать проверенное исключение . Вы можете выдать Exception, соответствующий существующий его подкласс (кроме RuntimeException и его подклассов, которые не проверены ), или пользовательский подкласс Exception (например, "CollectionBuildException"). См. Учебник Java по исключениям , чтобы освоиться с исключениями Java.

7 голосов
/ 31 января 2009

Вы не должны действительно ловить исключение и генерировать новое, такое же общее, как «новое исключение».

Вместо этого, если вы хотите вызвать исключение, просто сделайте следующее:

try {
    // Do some stuff here
}
catch (DivideByZeroException e) {
    System.out.println("Can't divide by Zero!"); 
} 
catch (IndexOutOfRangeException e) { 
    // catch the exception 
    System.out.println("No matching element found.");
}
catch (Throwable e) {
    throw e; // rethrow the exception/error that occurred
}

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

5 голосов
/ 13 апреля 2011

Только в двух местах вы должны увидеть слово Throwable в коде:

public static void main(String args[])
{
     try
     {
         // Do some stuff
     }
     catch(Throwable t)
     {

     }
 }

И

public class SomeServlet extends HttpServlet
{
      public void doPost(HttpRequest request, HttpResponse response)
      {
         try
         {
             // Do some stuff
         }
         catch (Throwable t)
         {
              // Log
         }
      }
 }
1 голос
/ 31 января 2009

throw new Exception(); - это то, что вы должны никогда делать в блоке перехвата, но вам, возможно, придется или вы захотите выполнить команду throw new SomeException(throwable); (с сохранением полной трассировки стека) вместо throw throwable; в порядке соответствовать API вашего метода, например когда он объявляет, что он выбрасывает SomeException, но вы вызываете код, который может выдать IOException, который вы не хотите добавлять к предложению throws вашего метода.

Вероятно, наиболее распространенным случаем является new RuntimeException(throwable);, чтобы вообще не иметь предложения throws. Многие люди скажут вам, что это ужасное злоупотребление, потому что вы должны использовать проверенные исключения. ИМО, они ошибочны, а проверенные исключения - это ошибка в дизайне языка Java, которая просто приводит к уродливому, не поддерживаемому коду.

1 голос
/ 31 января 2009

Throwable - это интерфейс, а не класс. Два класса расширяют Throwable, Exception и Error.

Правило: будьте как можно более конкретны при отлове исключений - это означает, например, перехват исключений вместо Throwable и IOException вместо исключений.

Не перехватывать ошибки - ошибки - это ошибки. Вместо этого исправьте код.

Если вам нужно поймать абсолютно все, используйте «catch Throwable», но это дурной тон.

0 голосов
/ 04 марта 2010

Вы также не должны использовать исключения как "тип возврата" ...

Если условие, которое вы выбрасываете, является распространенным, вы тратите огромное количество ресурсов, чтобы вернуть это условие в вызывающую подпрограмму. Исключения составляют дорогостоящие.

Я видел случаи, когда узкие циклы, которые создавали исключения как "отрицательные", например, При распределении идентификаторов эта процедура занимала около 99% процессорного времени. При изменении задокументированной возвращаемой константы она упала до 25%.

0 голосов
/ 01 февраля 2009

Как правило, вы не будете бросать или ловить Throwable. В частности, ошибки JVM (которые расширяют Error ()) не означают , означающие , которые могут быть обнаружены пользовательским кодом, если вы не выполняете странную работу на системном уровне.

Считайте "Throwable" языковым артефактом. Класс «Исключение» назван так, потому что он предназначен для программистов, когда они хотят, чтобы блок кода вышел «исключительно» - не выходя нормально или возвращая значение.

Это включает в себя как обычные ситуации с ошибками (под «обычными», я имею в виду, в отличие от ошибок JVM), так и места, где вы используете исключения в качестве механизма управления.

0 голосов
/ 01 февраля 2009

В конце концов, все исключения являются проблемой ... тоже, скажем, ошибки - это ошибки, ничего не значит.

Ошибки не являются ошибками - это проблемы, с которыми сталкивается виртуальная машина, например OutOfMemoryError. Исключения - это средство, которое текущая операция может использовать для уведомления о сбое и, возможно, для установления некоторого диагноза.

0 голосов
/ 31 января 2009

Throwable предназначен для захвата только контейнером или основным циклом вашей программы. Большую часть времени ловит вещи ниже Исключения, например, Ошибка не добавляет много возможностей программе, в конце концов, что вы можете сделать, если выдает VirtualError другие ошибки. Не много кроме лога и продолжения.

...