Обработка исключений
В процессе работы программы могут случаться различные непредвиденные проблемы.
Например:
- При скачивании файла оборвалось соединение...
-- Такое вполне может произойти, например если у пользователя плохой сигнал wi-fi.
- При попытке записать файл на USB устройство и устройство оказалось недоступно...
-- Такое может случиться, если пользователь задел рукой USB устройство.
- При попытке выполнить запрос к базе данных, может оказаться, что она недоступна.
-- Такое может случиться, если сервер с БД выключился/перезагрузился и т.п.
Примеров можно приводить много. Любая из этих проблем, потенциально может вывести из строя вашу программу.
Ошибки в работе программы - это конечно плохо, и к сожалению они случаются. Было бы неплохо их максимально предсказывать и если они случаются, то лучше постараться быть вкурсе и держать ситуацию под контролем.
Хорошие новости
В java есть механизм обработки ошибок исключений!
Помимо того, что такой механизм существует, java вообще в некоторых случаях не скомпилируется, если вы не будете контролировать потенциально опасные места программы.
Попробуйте например запустить пример показанный ниже пример.
В файле Main.java
Ну и какой итог?
java: unreported exception java.net.UnknownHostException; must be caught or declared to be thrown
Java сообщает нам, что мы должны были перехватить исключение. Без этого, программа отказывается собираться.
- А зачем здесь это? Какие могут быть проблемы?
-- В данном примере, мы подключаемся к серверу, но может случиться ситуация, что сервер недоступен, и вот что тогда делать???
Вот как раз для того, чтобы java знала, что нужно делать в этой ситуации, мы должны обрабатывать исключения!
Определение: Исключения представляют собой события, которые возникают во время выполнения программы и могут привести к нарушению нормального потока выполнения.
Использование блоков try-catch
Блок try используется для обозначения участка кода, в котором может произойти исключение, а блок catch - для обработки возникшего исключения.
try - пытаться catch - ловить finally - в конце концов
Отлично, как это выглядит синтаксически понятно, теперь давайте допустим ошибку.
4
2
1
Exception in thread "main" java.lang.
ArrayIndexOutOfBoundsException
: Index 3 out of bounds for length 3
at Main5.main(Main.java:7)
Process finished with exit code 1
Как видно из примера, программа споткнулась на 7 строчке, из-за обращения к несуществующему индексу.
Попробуем записать код в блок try-catch
4
2
1
Program end
Exception in thread "main" java.lang.
ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
at Main5.main(Main.java:7)
Process finished with exit code 0
Отлично! Теперь вся программа корректно отработала и завершилась с code 0. Строка e.printStackTrace(); позволила нам увидеть, что случилось в процессе исполнения алгоритма, но обращение к элементу nums[3], не приводит к ошибке в программе.
Внимательный читатель заметит, что программа с массивом int[] nums = {4,2,1}; без try-catch всё-таки скомпилировалась и запустилась.
В примере со строкой Socket socket = new Socket("127.0.0.1", 9123); программа выдала ошибку на мементе компиляции.
В чём же разница, как это вообще работает?
Давайте разбираться...
В языке Java существует два типа исключений checked и unchecked.
Checked exception - это исключения, которые обязательно должны быть обработаны в коде или объявлены в сигнатуре метода с помощью ключевого слова throws. Компилятор Java требует обработки checked исключений для того, чтобы предотвратить возможные ошибки времени выполнения.
- По логике вещей, такого рода ситуации (ошибки) можно предвидеть.
Unchecked exception - это исключения, которые не требуют явного обработчика или объявления с помощью ключевого слова throws. Unchecked исключения наследуются от класса RuntimeException или его подклассов. В отличие от checked исключений, компилятор Java не требует обработки unchecked исключений
Иерархическая структура наследования классов

Обсудим логику создателей языка Java.
Error - это ошибки которые невозможно проконтроллировать на момент компиляции. Например
StackOverflow (переполнение стека), может возникнуть когда метод вызвал сам себя (рекурсивно) большое колличество раз.
Это серъёзная проблема, никакой try-catch тут не поможет!
RuntimeException - это исключения которые возникают во время выполнения программы, отсюда и название Run Time.
Как и с Error, компилятор не может предсказать их заранее, но в отличие от Error их можно обработать, если конечно вы понимаете, что, что-то может пойти не так.
И вот как раз в примере с массивом int[] nums = {4,2,1}; мы имеели дело с RuntimeException, поэтому программа скомпилировалась.
IOException - это исключения ввода-вывода IO - Input-Output.
Вполне очевидно, что при попытке записать что-то куда-то или прочитать откуда-то может возникнуть проблема.
Так давайте обяжем разработчиков в обязательном порядке обрабатывать эти исключения - подумали создатели java.
И поэтому, когда мы пытались запустить программу со строкой Socket socket = new Socket("127.0.0.1", 9123);, программа выдала ошибку на мементе компиляции.
Мы рассмотрели понятие обработки исключений и использование блоков try-catch для обеспечения надежности программного кода. Правильная обработка исключений позволяет предотвратить аварийное завершение программы и уведомить пользователя о возникших проблемах.
Не забывайте подкреплять теорию практикой и дивгайтесь дальше!