Сделать программу идеальной сложно, и в ней неизбежно будут возникать различные отклонения. Например, в самой программе есть ошибка, например, в принтере заканчивается бумага при печати программы или недостаточно памяти. Чтобы устранить эти исключения, нам нужно знать, почему возникло исключение. Для некоторых распространенных исключений мы также можем предоставить определенные планы реагирования. Обработка исключений в языке C просто реализуется через возвращаемые значения функции, но значение возвращаемого значения часто определяется соглашением. Программистам необходимо запросить большой объем информации, прежде чем они смогут найти неясную причину. Объектно-ориентированные языки, такие как C++, Java и Python, часто имеют более сложные механизмы обработки исключений. Здесь обсуждается механизм обработки исключений в Java.
Обработка исключений Java
Обработка исключений
Большая часть механизма обработки исключений Java заимствована из C++. Это позволяет программистам пропускать проблемы, которые временно невозможно обработать, чтобы продолжить последующую разработку, или позволяет программе более разумно обрабатывать исключения.
Java использует некоторые специальные объекты для представления аномальных условий. Такие объекты называются объектами исключений. При возникновении исключения Java генерирует объект, представляющий текущую ситуацию, на основе предустановленных настроек. Так называемый бросок – это особый способ возврата. Поток будет приостанавливать и завершать вызовы методов слой за слоем, пока не встретит обработчик исключений. Обработчик исключений может перехватить объект исключения и принять решение о следующем действии на основе объекта, например:
Напомните пользователю обработать исключения и продолжить работу программы, чтобы выйти из программы.
...
Обработчик исключений выглядит так, он состоит из блоков try, catch,finally и последующих. наконец-то не требуется.
попробуйте { ...;}catch() { ...;}catch() { ...;} наконец { ...;}
Этот обработчик исключений отслеживает программный блок после попытки. Круглые скобки catch имеют параметр, который представляет тип перехватываемого исключения. catch захватит соответствующий тип и его производные классы. Программный блок после try содержит операции, которые необходимо выполнить для типа исключения. Программный блок, отслеживаемый try, может генерировать несколько типов исключений, поэтому обработчик исключений может иметь несколько модулей catch. Программный блок после, наконец, представляет собой программу, которая должна выполняться независимо от возникновения исключения.
Мы тестируем программы, которые могут работать неправильно и требуют мониторинга, и разрабатываем решения для обработки исключений в catch.
Ниже приведена частичная программа Java, использующая обработку исключений. Часть программы try считывает строки текста из файла. В процессе чтения файла может возникнуть исключение IOException:
BufferedReader br = new BufferedReader (new FileReader («file.txt»)); попробуйте { StringBuilder sb = new StringBuilder (); while (line! = null) { sb.append (line) ; sb.append("/n"); строка = br.readLine() } Строка всего = sb.toString();} catch(IOException e) { e.printStackTrace(); System.out.println("Проблема ввода-вывода");}finally { br.close();}
Если мы поймаем объект класса IOException e, мы сможем работать с ним. Например, вызовите метод printStackTrace() объекта, чтобы распечатать текущий статус стека. Кроме того, мы также напечатали сообщение «Проблема ввода-вывода» на среднем уровне.
Независимо от того, возникло исключение или нет, программа в конечном итоге войдет в блокfinally. Закрываем файл в блокеfinally и очищаем ресурсы, занятые файловым дескриптором.
тип исключения
Все классы исключений в Java наследуются от класса Trowable. Объект класса Throwable можно бросить (бросить).
Оранжевый: флажок не установлен; синий: флажок установлен;
Бросаемые объекты можно разделить на две группы. Одна группа — это непроверяемые исключения. Для этой группы исключений часто не используются механизмы обработки исключений, в том числе:
1. Класс Error обычно относится к внутренним ошибкам Java и ошибкам, таким как исчерпание ресурсов. Когда возникает Ошибка (и ее производные), мы не можем устранить ее на уровне программирования, поэтому нам следует выйти из программы напрямую.
2. Класс Exception имеет специальный производный класс RuntimeException. RuntimeException (и его производные) вызваны самой Java-программой, то есть из-за ошибок программиста во время программирования. RuntimeException можно полностью избежать, изменив программу Java. Например, преобразование объекта одного типа в другой тип без отношения наследования является исключением ClassCastException. Таких аномалий следует и можно избегать.
Остальные являются проверенными исключениями. Эти классы возникают в результате взаимодействия программирования со средой, которое вызывает ошибки в программе во время выполнения. Например, при чтении файла возникает исключение IOException из-за ошибки в самом файле. Другой пример: сетевой сервер временно меняет URL-адрес, вызывая исключение MalformedURLException. Файловая система и сетевой сервер находятся за пределами среды Java и не контролируются программистом. Если программисты могут предвидеть исключения, они могут использовать механизм обработки исключений для разработки планов реагирования. Например, при возникновении проблемы с файлом системный администратор получает предупреждение. Другой пример: когда возникает проблема с сетевым сервером, пользователь получает напоминание и ждет восстановления сетевого сервера. Механизм обработки исключений в основном используется для обработки таких исключений.
выдать исключение
В приведенной выше программе исключение возникает из-за нашего вызова API Java IO. Мы также можем создавать исключения в наших собственных программах, например, для следующего класса батарей, который имеет методы зарядки и использования:
public class Test { public static void main(String[] args) { Battery aBattery = new Battery(); aBattery.chargeBattery(0.5); aBattery.useBattery(-0.5 }}class Battery { /** * увеличить батарею * / public void chargeBattery(double p) { // power <= 1 if (this.power + p < 1.) { this.power = this.power + p; } else { this.power = 1.; } } /** * потреблять батарею */ public boolean useBattery(double p) { try { test(p); catch(Exception e) { System. out.println("перехватить исключение"); System.out.println(e.getMessage()); p = 0.0; } if (this.power >= p) { this.power = this.power - p; return true; } else { this.power = 0.0; return false } } /** * использование теста */ Private void test(double p) выдает исключение // Я просто выбрасываю, не обрабатываю { if ( p < 0) {Exception e = new Exception("p должно быть положительным"); throw e; } Private Double Power = 0.0;
useBattery() указывает на использование батареи. В методе useBattery() есть параметр, указывающий количество использованной электроэнергии. Мы используем метод test() для проверки этого параметра. Если этот параметр отрицательный, мы думаем, что есть исключение, и выбрасываем его.
В тесте, когда возникает исключение (p < 0), мы создаем объект Exception e и используем строку в качестве параметра. Строка содержит информацию об исключении, и этот параметр не является обязательным. Используйте throw, чтобы создать объект Exception.
У нас есть обработчик исключений в useBattery(). Поскольку метод test() не обрабатывает генерируемое им исключение напрямую, а выдает исключение в верхний метод useBattery(), нам нужно объяснить выдачу исключения в определении test().
(Предполагая, что обработчик исключений находится не в useBattery(), а в методе main() более высокого уровня, нам также необходимо добавить throws Exception в определение useBattery().)
В catch мы используем метод getMessage() для извлечения информации, содержащейся в исключении. Результаты запуска вышеуказанной программы следующие:
catch Exceptionp должен быть положительным
В обработчике исключений мы перехватим любое исключение класса Exception или его производных. Часто это не помогает нам выявить проблемы, особенно когда программа может генерировать несколько исключений. Мы можем предоставить более конкретный класс для захвата.
Пользовательское исключение
Мы можем создавать новые классы исключений посредством наследования. При наследовании нам часто необходимо переопределить конструктор. Исключения имеют два конструктора: один без параметров и один со строковым параметром. например:
класс BatteryUsageException расширяет Exception {public BatteryUsageException () {} public BatteryUsageException (String msg) { super (msg }});
Мы можем предоставить больше методов и информации, связанных с исключениями, в производных классах.
При настройке исключений будьте осторожны с тем, от какого базового класса вы наследуете. Более конкретный класс должен содержать больше информации об исключениях, например IOException или Exception.
Подвести итог
Обработка исключений решает проблемы, но она также и создает проблемы. В больших проектах чрезмерная и детальная обработка исключений часто приводит к тому, что программа становится беспорядочной. Обработка исключений по своей конструкции непроста, и ее следует использовать с осторожностью.