Недостаточное время проверки проверенных и непроверенных исключений

Я уже прочитал все, что мог, и я до сих пор не понимаю, как использовать проверенные и непроверенные исключения. Думаю, я не могу понять концепцию. Я читал вокруг StackOverflow, что лучше использовать не проверенные, а не проверенные исключения, но Eclipse заставляет меня использовать проверенные исключения, как в FileNotFoundException (AFAIK, если Eclipse заставляет меня вставлять блок try/catch, это проверенное исключение). Мне интересно, есть ли способ перевести проверенный на непроверенный? Какого черта, как само по себе? Я не понимаю, для чего нужно обработать исключение.

У меня есть этот пример здесь, мне бы очень хотелось знать, как обрабатывать (?) это. Это проверенное исключение, правильно?

public void readFile() {
    File foo = new File("./foo.bar");
    try {
        BufferedReader bufferedReader = new BufferedReader(new FileReader(foo));
    } catch (FileNotFoundException e) {
        // What should I do here?
    }
    getDataFromFile(bufferedReader);
}

Я видел разные вещи, которые люди здесь делают. Некоторые печатают трассировку стека, что я обычно делаю, и я не вижу проблемы с ней. Это дает мне информацию, которую мне нужно отлаживать. Некоторые люди игнорируют их, я думаю, что это не должно быть сделано (я видел, как JNode OS booter игнорировал исключение). Некоторые люди просто добавляют объявление throws в подпись. Некоторые бросают больше исключений внутри этой вещи! (Я думаю, может быть, это то, что с помощью unchecked вместо проверенных означает?)

Кроме того, если вы добавите объявление throws, вы будете вынуждены добавить блок try/catch дальше, и это неудобно, если у вас очень большое приложение. Извините, но я просто невежественна. Полностью. Я пытаюсь изучить хороший и элегантный дизайн, и это мучает меня.

Ответ 1

Неконтролируемое исключение

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

Это подкласс RuntimeException (который является подклассом Exception) и обычно реализуется с использованием IllegalArgumentException, NullPointerException или IllegalStateException

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


Проверено исключение

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

Это подкласс Exception.

От: Исключения


В вашем примере

Файл, который не присутствует, - это случай, который вам нужно обрабатывать, как это могло бы произойти, даже в производственном коде, если преобладают определенные условия (полный диск). Это делает это проверенным исключением.


Работа с исключением:

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

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

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

Ответ 2

Во-первых, исключения - ваш друг:) - Нет, действительно. Исключения являются довольно мощным и безопасным способом обработки ошибок.

В принципе, разница между проверенными и непроверенными исключениями в Java является предполагаемой реакцией на исключение:

Проверенное исключение обычно используется для передачи какого-то "неожиданного" результата операции вызывающему, который, как считается, хочет обработать это исключительное состояние явно.

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

В вашем примере вы, вероятно, будете так:

public void readFile() {
    File foo = new File("./foo.bar");
    try {
        BufferedReader bufferedReader = new BufferedReader(new FileReader(foo));
        getDataFromFile(bufferedReader);  // If the file could not be found above, this will never execute!
    } catch (IOException e) {
        // React, e.g.:
        System.out.println("Data could not be read due to an IO error.");
    }

}

Повторное бросание исключения или обертывание одного исключения в другое не является чем-то необычным. Например, когда удаляется IOException, вы можете выполнить некоторую очистку, закрыть некоторые открытые файлы или тому подобное, прежде чем передавать исключение как есть или изменить его, чтобы он мог обработать исключение соответствующим образом.

Как вы действительно справляетесь с конкретным исключением, в значительной степени полностью зависит от вас. В зависимости от пользователя (например, самостоятельно) и среды, в которой выполняется печать вашего кода, stacktrace может быть в порядке. Или, может быть, вы хотите повторить то, что вы только что сделали после некоторой паузы. Или, в приведенном примере, вы могли бы показать сообщение пользователю и попросить его повторно ввести имя файла, & c.

Последнее, кстати, может быть эффективно использовано разными классами исключений: A FileNotFoundException (который является подклассом IOException) может быть извлечен из-за взаимодействия с пользователем; голый IOException вполне может считаться неустранимым, поскольку он может в худшем случае даже указывать на какой-то аппаратный сбой.

Ответ 3

Возьмем ваш пример (модифицированный) для объяснения.

public void readFile() {
    BufferedReader bufferedReader = null;
    try {
            File foo = new File("./foo.bar");
        bufferedReader = new BufferedReader(new FileReader(foo));
    } catch (FileNotFoundException e) {
        // What should I do here?
    }
    getDataFromFile(bufferedReader);
}

Когда вы получаете исключение FileNotFoundException, тогда ваш bufferedReader не инициализируется файловым потоком. В этом случае ваш следующий оператор, т.е. getDataFromFile(bufferedReader);, не будет работать, поскольку для чтения данных не существует буферизованного считывателя.

Итак, в блоке catch вы можете сделать следующее:

  • Выбросить новое настраиваемое исключение и вернуться из программы
  • Попробуйте устранить проблему при повторном получении дескриптора файла (один пример может использовать файл по умолчанию в этом случае), поэтому bufferedReader будет правильно инициализирован.

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

С другой стороны, неконтролируемые исключения, такие как NullPointerException, трудно идентифицировать во время компиляции и могут остаться незамеченными. Если они произошли и не обработаны, они вызывают проблемы во время выполнения.

Ответ 4

Проверенные исключения - это боль в заднице.

Извините, что использовал такой тупой язык, но они являются одной из худших ошибок дизайна Java! Если вам приходится иметь дело с устаревшими API-интерфейсами, которые по-прежнему используют проверенные исключения, такие как Eclipse или собственные API Java, то, что я лично делаю, заключается в том, чтобы обернуть их в мои собственные непроверенные исключения. Хорошая практика - использовать свой собственный класс меток. Это поможет вам распознать эти исключения как вызванные вашим кодом, например, в файлах журнала или при отладке.

Лично я с большим удовольствием вызываю свой класс тегов BullshitFree, чтобы я мог повторно проверить отмеченные исключения следующим образом

try {
    // call to legacy API that still uses checked exceptions
} catch(CheckedException exception) {
    throw new BullshitFree(exception);
}

Убедитесь, что класс исключений BullshitFree фактически расширяет RuntimeException, чтобы он не был отмечен!

В случае вашего примера кода есть два варианта. Если есть способ восстановить это, например, создав файл или сообщив об ошибке обратно пользователю, сделайте это. Если нет, или если это всего лишь небольшой script, который вы используете для себя, оберните его в исключение BullshitFree и потратите оставшуюся часть дня на изучение Ruby или другого хорошо продуманного языка...

Ваше перемещение может отличаться.