1. Excepții
>
În cele din urmă, programatorii s-au gândit să standardizeze și să automatizeze gestionarea erorilor. Acest lucru s-a întâmplat când au fost inventate excepții . Acum mecanismul de excepție gestionează 80% din situațiile excepționale.
Dacă un savant a venit cu excepții, probabil că a fost subiectul tezei sale de doctorat. Dacă un programator a venit cu asta, atunci poate că a primit o palmă prietenoasă pe spate de la un coleg: „Se pare în regulă, frate”.
Când apare o eroare într-un program Java, cum ar fi împărțirea cu 0
, se întâmplă câteva lucruri minunate:
Primul pas
Este creat un obiect excepție special, care conține informații despre eroarea care a apărut.
Totul în Java este un obiect, iar excepțiile nu sunt excepții 🙂 Obiectele excepție au propriile lor clase și singurul lucru care le diferențiază de clasele obișnuite este că moștenesc clasa Throwable
.
Pasul doi
Obiectul excepție este „aruncat”. Poate că formularea de aici ar putea fi mai bună. „Aruncarea unei excepții” este mai degrabă ca declanșarea unei alarme de incendiu sau sunetul unei alerte „DEFCON 1”.
Când o excepție este aruncată la mașina Java, funcționarea normală a programului se oprește și încep „protocoalele de urgență”.
Pasul trei
Metoda în care a fost aruncată excepția iese imediat. Excepția este transmisă metodei de apelare, care, de asemenea, iese imediat. Și așa mai departe în lanț până când main
metoda iese. Când main
metoda se termină, la fel și programul.
Exemplu:
Cod | Ieșire de consolă |
---|---|
|
|
O excepție apare pe linia 20: împărțirea cu 0. Mașina Java creează imediat o excepție - un ArithmeticException
obiect și îl „aruncă” metodei.
Metoda divide()
se termină imediat, așa că nu vedem niciodată șirul: Nu s-a întâmplat nimic groaznic: 0. Programul revine la metodă endTheWorld()
, iar situația se repetă: există o excepție netratată în sistem, ceea ce înseamnă că endTheWorld()
și metoda se termină anormal. Apoi main
metoda se termină, iar programul se oprește.
Care este scopul acestor excepții? Ei bine, puteți scrie propriul cod pentru a prinde anumite tipuri de excepții și vă puteți scrie propria logică pentru a gestiona situații excepționale.
2. Obțineți excepții:try-catch
Java are un mecanism de captare a excepțiilor care vă permite să opriți această terminare anormală a metodelor. Arata cam asa:
try
{
// Code where an exception might occur
}
catch(ExceptionType name)
{
// Exception handling code
}
Acest construct se numește try-catch
bloc.
Codul în care pot apărea excepții este înfășurat în acolade, precedat de cuvântul try
.
După acolade, avem cuvântul catch
cheie și, între paranteze, declarația unei variabile de excepție . Aceasta este urmată de acolade care încapsulează codul care urmează să fie executat dacă apare o excepție de tipul specificat .
Dacă nu sunt aruncate excepții în timpul execuției „ codului primar ”, atunci codul din interiorul blocului catch nu va fi executat. Dacă apare o excepție, atunci va fi (dacă tipul excepției aruncate este același cu tipul variabilei din paranteze).
Exemplu:
Cod | Ieșire de consolă |
---|---|
|
|
3. catch
Blocuri multiple
În teorie, într-un bloc de cod pot fi aruncate tot felul de excepții. Unele veți dori să vă descurcați într-un fel, altele într-un alt fel, iar altele veți decide să nu le gestionați deloc.
Dezvoltatorii Java au decis să vă ajute și să vă permită să scrieți nu unul, ci multe catch
blocuri după try
bloc.
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
}
Exemplu:
Cod | Ieșire de consolă |
---|---|
|
|
4. Ordinea catch
blocurilor
Excepțiile care apar într-un try
bloc pot fi capturate doar de un singur catch
bloc. Nu puteți avea o situație de gestionare a excepțiilor în care codul din mai multe catch
blocuri este executat.
Dar ordinea blocurilor contează.
Puteți avea o situație în care o excepție ar putea fi prinsă de mai multe blocuri. Dacă acesta este cazul, atunci excepția va fi prinsă de oricare bloc de capturătry
care vine primul (cel mai aproape de bloc).
Cum poți avea o situație în care mai multe blocuri de captură pot prinde aceeași excepție?
Toate excepțiile aparțin unei singure ierarhii de moștenire - vezi diagrama.
Un ArithmeticException
obiect poate fi atribuit unei variabile al cărei tip este ArithmeticException
sau oricare dintre clasele sale strămoși: RuntimeException
și Exception
— Throwable
vezi diagrama.
Vom vorbi mai multe despre moștenire și clase de strămoși la nivelul 21.
Acest cod se va compila foarte bine:
Beneficiile moștenirii: |
---|
|
Deci, puteți prinde un ArithmeticException
cu oricare dintre cele 4 catch
blocuri de mai sus.
Exemplul 1:
Cod | Ieșire de consolă |
---|---|
|
|
În acest exemplu, ArithmeticException
poate fi prins atât de blocuri catch (Exception e)
cât și catch (ArithmeticException e)
. Va fi prins de blocul cel mai apropiat de try
bloc — primul catch
bloc.
Pentru a evita surprizele, cel mai bine este să plasați catch
blocuri care pot prinde aproape orice excepție aproape de sfârșitul listei de catch
blocuri.
Tipul Throwable
este, în general, capabil să prindă orice excepție posibilă în Java . Dacă îl puneți în primul catch
bloc, atunci codul nu se va compila, deoarece compilatorul știe că există blocuri de cod inaccesibile.
GO TO FULL VERSION