1. Изключения
>
Най-накрая програмистите се сетиха да стандартизират и автоматизират обработката на грешки. Това се случи, когато бяха измислени изключения . Сега механизмът за изключения обработва 80% от изключителните ситуации.
Ако някой учен направи изключения, това вероятно е било темата на неговата or нейната докторска дисертация. Ако програмист го е измислил, тогава той може да е получил приятелско потупване по гърба от колега: "Изглежда добре, брато."
Когато възникне грешка в Java програма, като деление на 0
, се случват някои чудесни неща:
Първа стъпка
Създава се специален обект за изключение, който съдържа информация за възникналата грешка.
Всичко в Java е обект и изключенията не са изключения 🙂 Обектите с изключения имат свои собствени класове и единственото нещо, което ги отличава от обикновените класове е, че наследяват класа Throwable
.
Стъпка втора
Обектът за изключение е "хвърлен". Може би формулировката тук би могла да бъде по-добра. „Подаване на изключение“ е по-скоро като задействане на пожарна аларма or прозвучаване на предупреждение „DEFCON 1“.
Когато бъде хвърлено изключение към Java машината, нормалната работа на програмата спира и започват „спешни протоколи“.
Стъпка трета
Методът, в който е хвърлено изключението, излиза веднага. Изключението се предава на извикващия метод, който също излиза незабавно. И така надолу по веригата, докато main
методът излезе. Когато main
методът се прекрати, програмата също.
Пример:
Код | Конзолен изход |
---|---|
|
|
Възниква изключение на ред 20: деление на 0. Java машината незабавно създава изключение — ArithmeticException
обект и го „хвърля“ към метода.
Методът divide()
приключва незабавно, така че никога не виждаме низа: Нищо ужасно не се е случило: 0. Програмата се връща към метода endTheWorld()
и ситуацията се повтаря: в системата има необработено изключение, което означава, че методът endTheWorld()
също прекратява необичайно. След това main
методът се прекратява и програмата спира.
Каква е целта на тези изключения? Е, можете да напишете свой собствен code за улавяне на определени видове изключения и да напишете своя собствена логика за справяне с изключителни ситуации.
2. Улавяне на изключения:try-catch
Java има механизъм за улавяне на изключения, който ви позволява да спрете това необичайно прекратяване на методи. Изглежда така:
try
{
// Code where an exception might occur
}
catch(ExceptionType name)
{
// Exception handling code
}
Тази конструкция се нарича try-catch
блок.
Кодът, при който могат да възникнат изключения, е увит във фигурни скоби, предшествани от думата try
.
След фигурните скоби имаме catch
ключовата дума и, в скобите, декларацията на променлива за изключение . Това е последвано от фигурни скоби, които обгръщат codeа, който трябва да бъде изпълнен, ако възникне изключение от посочения тип .
Ако не бъдат хвърлени изключения по време на изпълнението на " първичния code ", тогава codeът вътре в блока catch няма да бъде изпълнен. Ако възникне изключение, то ще бъде (ако типът на хвърленото изключение е същият като типа на променливата в скобите).
Пример:
Код | Конзолен изход |
---|---|
|
|
3. Множество catch
блокове
На теория всяHowви изключения могат да бъдат хвърлени в блок от code. С някои ще искате да се справите по един начин, с други по друг начин, а с трети ще решите да не се справяте изобщо.
Разработчиците на Java решиха да ви помогнат и ви позволиха да пишете не един, а много catch
блокове след try
блока.
try
{
// Code where an exception might occur
}
catch (ExceptionType1 name1)
{
// Code for handling ExceptionType1
}
catch (ExceptionType2 name2)
{
// Code for handling ExceptionType2
}
catch (ExceptionType3 name3)
{
// Code for handling ExceptionType3
}
Пример:
Код | Конзолен изход |
---|---|
|
|
4. Ред на catch
блоковете
Изключенията, които възникват в try
блок, могат да бъдат уловени само от един catch
блок. Не можете да имате ситуация на обработка на изключения, при която codeът от множество catch
блокове се изпълнява.
Но редът на блоковете има meaning.
Може да имате ситуация, при която изключение може да бъде уловено от множество блокове. Ако случаят е такъв, тогава изключението ще бъде уловено от който блок catch е първи (най-близо до try
блока).
Как може да имате ситуация, в която множество catch блокове могат да хванат едно и също изключение?
Всички изключения принадлежат към една единствена йерархия на наследяване - вижте диаграмата.
Обект ArithmeticException
може да бъде присвоен на променлива, чийто тип е ArithmeticException
or който и да е от неговите предшестващи класове: RuntimeException
, Exception
и Throwable
— вижте диаграмата.
Ще говорим повече за класовете на наследяване и предшественици в ниво 21.
Този code ще се компorра добре:
Предимства на наследството: |
---|
|
Така че можете да хванете ArithmeticException
с някой от 4-те catch
блока по-горе.
Пример 1:
Код | Конзолен изход |
---|---|
|
|
В този пример ArithmeticException
може да бъде уловен Howто от блоковете, catch (Exception e)
така и catch (ArithmeticException e)
от блоковете. Ще бъде уловен от блока, който е най-близо до try
блока — първият catch
блок.
За да избегнете изненади, най-добре е да поставите catch
блокове, които могат да уловят почти всяко изключение, близо до края на списъка с catch
блокове.
Типът Throwable
обикновено е в състояние да улови всяко възможно изключение в Java . Ако го поставите в първия catch
блок, codeът няма да се компorра, тъй като компилаторът знае, че има недостижими блокове code.
GO TO FULL VERSION