Исключениями или исключительными ситуациями (состояниями) называются ошибки, возникшие в программе во время её работы.
Все исключения в Java являются объектами. Поэтому они могут порождаться не только автоматически при возникновении исключительной ситуации, но и создаваться самим разработчиком.
Иерархия классов исключений:
Исключения делятся на несколько классов, но все они имеют общего предка — класс

Throwable
. Его потомками являются подклассы Exception
и Error
.
Исключения (Exceptions
) являются результатом проблем в программе, которые в принципе решаемы и предсказуемы. Например, произошло деление на ноль в целых числах.
Ошибки (Errors
) представляют собой более серьёзные проблемы, которые, согласно спецификации Java, не следует пытаться обрабатывать в собственной программе, поскольку они связаны с проблемами уровня JVM. Например, исключения такого рода возникают, если закончилась память, доступная виртуальной машине. Программа дополнительную память всё равно не сможет обеспечить для JVM.
В Java все исключения делятся на три типа: контролируемые исключения (checked
) и неконтролируемые исключения (unchecked
), к которым относятся ошибки (Errors
) и исключения времени выполнения (RuntimeExceptions
, потомок класса Exception
).
Контролируемые исключения представляют собой ошибки, которые можно и нужно обрабатывать в программе, к этому типу относятся все потомки класса Exception
(но не RuntimeException
).
Обработка исключения может быть произведена с помощью операторов try…catch
, либо передана внешней части программы. Например, метод может передавать возникшие в нём исключения выше по иерархии вызовов, сам его не обрабатывая.
Неконтролируемые исключения не требуют обязательной обработки, однако, при желании, можно обрабатывать исключения класса RuntimeException
.
Откомпилируем и запустим такую программу:
class Main {
public static void main(String[] args) {
int a = 4;
System.out.println(a/0);
}
}
В момент запуска на консоль будет выведено следующее сообщение:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.main(Main.java:4)
Из сообщения виден класс случившегося исключения — ArithmeticException
. Это исключение можно обработать:
class Main {
public static void main(String[] args) {
int a = 4;
try {
System.out.println(a/0);
} catch (ArithmeticException e) {
System.out.println("Произошла недопустимая арифметическая операция");
}
}
}
Теперь вместо стандартного сообщения об ошибке будет выполняться блок catch
, параметром которого является объект e соответствующего исключению класса (самому объекту можно давать любое имя, оно потребуется в том случае, если мы пожелаем снова принудительно выбросить это исключение, например, для того, чтобы оно было проверено каким-то ещё обработчиком).
В блок try
при этом помещается тот фрагмент программы, где потенциально может возникнуть исключение.
Одному try
может соответствовать сразу несколько блоков catch с разными классами исключений.
import java.util.Scanner;
class Main {
public static void main(String[] args) {
int[] m = {-1,0,1};
Scanner sc = new Scanner(System.in);
try {
int a = sc.nextInt();
m[a] = 4/a;
System.out.println(m[a]);
} catch (ArithmeticException e) {
System.out.println("Произошла недопустимая арифметическая операция");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Обращение по недопустимому индексу массива");
}
}
}
Если запустив представленную программу, пользователь введётся с клавиатуры 1 или 2, то программа отработает без создания каких-либо исключений.
Если пользователь введёт 0, то возникнет исключение класса ArithmeticException
, и оно будет обработано первым блоком catch
.
Если пользователь введёт 3, то возникнет исключение класса ArrayIndexOutOfBoundsException
(выход за приделы массива), и оно будет обработано вторым блоком catch
.
Если пользователь введёт нецелое число, например, 3.14, то возникнет исключение класса InputMismatchException
(несоответствие типа вводимого значение), и оно будет выброшено в формате стандартной ошибки, поскольку его мы никак не обрабатывали.
Можно, однако, добавить обработчик для класса Exception
, поскольку этот класс родительский для всех остальных контролируемых исключений, то он будет перехватывать любые из них (в том числе, и InputMismatchException
).
import java.util.Scanner;
class Main {
public static void main(String[] args) {
int[] m = {-1,0,1};
int a = 1;
Scanner sc = new Scanner(System.in);
try {
a = sc.nextInt();
m[a-1] = 4/a;
System.out.println(m[a]);
} catch (ArithmeticException e) {
System.out.println("Произошла недопустимая арифметическая операция");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Обращение по недопустимому индексу массива");
} catch (Exception e) {
System.out.println("Произошло ещё какое-то исключение");
}
}
}
Поскольку исключения построены на иерархии классов и подклассов, то сначала надо пытаться обработать более частные исключения и лишь затем более общие. То есть поставив первым (а не третьим) блок с обработкой исключения класса Exception
, мы бы никогда не увидели никаких сообщений об ошибке, кроме «Произошло ещё какое-то исключение» (все исключения перехватились бы сразу этим блоком и не доходили бы до остальных).
Необязательным добавлением к блокам try…catch
может быть блок finally
. Помещенные в него команды будут выполняться в любом случае, вне зависимости от того, произошло ли исключение или нет. При том, что при возникновении необработанного исключения оставшаяся после генерации этого исключения часть программы — не выполняется. Например, если исключение возникло в процессе каких-то длительных вычислений, в блоке finally
можно показать или сохранить промежуточные результаты.
Ссылка на первоисточник: Исключения и их обработка
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
но может оказаться так, что символ первый в строке и тогда проверка (chars[i-1] == ' ') приведет к ошибке ArrayIndexOutOfBoundsException — и тут то я уже предугадываю, что такое возможно, и обрабатываю исключение. То есть это не случайная ошибка и надо внимательно писать код или что то там еще а нет. это заведомо checked ситуация
1. Контролируемые исключения (checked)
2. Неконтролируемые исключения (unchecked), к которым относятся ошибки (Errors)
3. Исключения времени выполнения (RuntimeExceptions, потомок класса Exception).
P.S. Да и если «читать по тексту», то тогда в тексте «В Java все исключения делятся на три типа: контролируемые исключения (checked) и неконтролируемые исключения (unchecked), к которым относятся ошибки (Errors) и исключения времени выполнения (RuntimeExceptions, потомок класса Exception).» перед второй «и» должна быть запятая по смыслу (+ первая «и» ни к чему тогда).
Стоит обратить внимание на схему иерархии классов — наглядная демонстрация.
Ссылаюсь на материал. По ссылке достаточно подробно описана ситуация.
1. Errors (unchecked) (extends Throwable);
2. Exception (checked) (extends Throwable);
3. RunTimeExceprions (unchecked) (extends Exceprion);
Насчёт знаков препинания претензий не имею. Текст читается легко:
аки
Насчет знаков препинания — пример конфликтует с вашим утверждением, т.к. в вашем примере ДВА синонима, а к последнему идет расшифровка. В тексте было сказано, что типов ТРИ. После двоеточия идет перечисление. И если дело обстоит так, как вы сказали (что третий тип — RuntimeExceptions), тогда оборот "к которым относятся ошибки (Errors)" должен обособляться запятыми + "и" идет второй раз в перечислении. Если же типов ДВА — тогда с грамматикой все правильно.
Вы говорите ТРИ типа checked, unchecked и unchecked ничего не смущает? :)
на ДВА типа?