1. Tipuri de excepții
Toate excepțiile sunt împărțite în 4 tipuri, care sunt de fapt clase care se moștenesc unele pe altele.
Throwable
clasă
Clasa de bază pentru toate excepțiile este Throwable
clasa. Clasa Throwable
conține codul care scrie stiva de apeluri curentă (urma stivă a metodei curente) într-o matrice. Vom afla ce este o urmă de stivă puțin mai târziu.
Operatorul de aruncare poate accepta doar un obiect care derivă din Throwable
clasă. Și, deși teoretic poți scrie cod ca throw new Throwable();
, nimeni nu face asta de obicei. Scopul principal al Throwable
clasei este de a avea o singură clasă părinte pentru toate excepțiile.
Error
clasă
Următoarea clasă de excepție este Error
clasa, care moștenește direct Throwable
clasa. Mașina Java creează obiecte ale Error
clasei (și descendenții acesteia) atunci când au apărut probleme serioase . De exemplu, o defecțiune hardware, memorie insuficientă etc.
De obicei, ca programator, nu poți face nimic într-o situație în care o astfel de eroare (de tipul pentru care Error
ar trebui aruncat) a apărut în program: aceste erori sunt prea grave. Tot ce puteți face este să notificați utilizatorul că programul se blochează și/sau să scrieți toate informațiile cunoscute despre eroare în jurnalul programului.
Exception
clasă
Clasele Exception
și RuntimeException
sunt pentru erori obișnuite care apar în operarea multor metode. Scopul fiecărei excepții aruncate este să fie prins de un catch
bloc care știe să o gestioneze corect.
Atunci când o metodă nu își poate finaliza activitatea dintr-un motiv oarecare, ar trebui să notifice imediat metoda de apelare, lansând o excepție de tipul adecvat.
Cu alte cuvinte, dacă o variabilă este egală cu null
, metoda va arunca un NullPointerException
. Dacă argumentele incorecte au fost transmise metodei, aceasta va arunca un InvalidArgumentException
. Dacă metoda se împarte accidental la zero, va arunca un ArithmeticException
.
RuntimeException
clasă
RuntimeExceptions
sunt un subset al Exceptions
. Am putea spune chiar că RuntimeException
este o versiune ușoară a excepțiilor obișnuite ( Exception
) — sunt impuse mai puține cerințe și restricții pentru astfel de excepții
Veți învăța diferența dintre Exception
și RuntimeException
mai târziu.
2. Throws
: excepții verificate
Toate excepțiile Java se încadrează în 2 categorii: bifate și nebifate .
Toate excepțiile care moștenesc RuntimeException
sau Error
sunt considerate excepții neverificate . Toate celelalte sunt excepții bifate .
La douăzeci de ani după ce au fost introduse excepții verificate, aproape fiecare programator Java consideră asta ca pe o eroare. În cadrele moderne populare, 95% din toate excepțiile sunt neverificate. Limbajul C#, care aproape a copiat Java exact, nu a adăugat excepții bifate .
Care este principala diferență dintre excepțiile bifate și neverificate ?
Există cerințe suplimentare impuse excepțiilor verificate . În linii mari, acestea sunt acestea:
Cerința 1
Dacă o metodă aruncă o excepție bifată , trebuie să indice tipul de excepție în semnătura sa . În acest fel, fiecare metodă care o apelează este conștientă de faptul că această „excepție semnificativă” ar putea apărea în ea.
Indicați excepțiile bifate după parametrii metodei după throws
cuvântul cheie (nu utilizați throw
cuvântul cheie din greșeală). Arata cam asa:
type method (parameters) throws exception
Exemplu:
excepție verificată | excepție nebifată |
---|---|
|
|
În exemplul din dreapta, codul nostru aruncă o excepție nebifată - nu este necesară nicio acțiune suplimentară. În exemplul din stânga, metoda aruncă o excepție bifatăthrows
, astfel încât cuvântul cheie este adăugat la semnătura metodei împreună cu tipul excepției.
Dacă o metodă se așteaptă să arunce mai multe excepții bifate , toate acestea trebuie specificate după throws
cuvântul cheie, separate prin virgule. Ordinea nu este importantă. Exemplu:
public void calculate(int n) throws Exception, IOException
{
if (n == 0)
throw new Exception("n is null!");
if (n == 1)
throw new IOException("n is 1");
}
Cerința 2
Dacă apelați o metodă care a verificat excepții în semnătură, nu puteți ignora faptul că le aruncă.
Trebuie fie să prindeți toate astfel de excepții adăugând catch
blocuri pentru fiecare, fie adăugându-le la o throws
clauză pentru metoda dvs.
Este ca și cum am spune: „ Aceste excepții sunt atât de importante încât trebuie să le prindem. Și dacă nu știm cum să le gestionăm, atunci oricine ar putea apela metoda noastră trebuie să fie anunțat că astfel de excepții pot apărea în ea.
Exemplu:
Imaginați-vă că scriem o metodă pentru a crea o lume populată de oameni. Numărul inițial de persoane este trecut ca argument. Deci trebuie să adăugăm excepții dacă sunt prea puțini oameni.
Crearea Pământului | Notă |
---|---|
|
Metoda poate arunca două excepții verificate :
|
Acest apel de metodă poate fi gestionat în 3 moduri:
1. Nu prinde nicio excepție
Acest lucru se face cel mai adesea atunci când metoda nu știe cum să gestioneze corect situația.
Cod | Notă |
---|---|
|
Metoda de apelare nu prinde excepțiile și trebuie să informeze pe alții despre ele: le adaugă la propria throws clauză |
2. Prinde unele dintre excepții
Ne ocupăm de erorile pe care le putem gestiona. Dar pe cei pe care nu îi înțelegem, îi aruncăm până la metoda de chemare. Pentru a face acest lucru, trebuie să adăugăm numele lor la clauza throws:
Cod | Notă |
---|---|
|
Apelantul prinde doar o excepție bifatăLonelyWorldException — . Cealaltă excepție trebuie adăugată la semnătura acesteia, indicând-o după throws cuvântul cheie |
3. Prinde toate excepțiile
Dacă metoda nu aruncă excepții de la metoda de apelare, atunci metoda de apelare este întotdeauna sigură că totul a funcționat bine. Și nu va putea lua nicio măsură pentru a remedia situații excepționale.
Cod | Notă |
---|---|
|
Toate excepțiile sunt prinse în această metodă. Apelantul va fi încrezător că totul a mers bine. |
3. Prinderea mai multor excepții
Programatorii chiar urăsc să dubleze codul. Au venit chiar și cu un principiu de dezvoltare corespunzător - DRY : Don't Repeat Yourself. Dar când se gestionează excepții, există ocazii frecvente când un try
bloc este urmat de mai multe catch
blocuri cu același cod.
Sau ar putea fi 3 catch
blocuri cu același cod și alte 2 catch
blocuri cu alt cod identic. Aceasta este o situație standard când proiectul dumneavoastră gestionează excepțiile în mod responsabil.
Începând cu versiunea 7, în limbajul Java a adăugat posibilitatea de a specifica mai multe tipuri de excepții într-un singur catch
bloc. Arata cam asa:
try
{
// Code where an exception might occur
}
catch (ExceptionType1 | ExceptionType2 | ExceptionType3 name)
{
// Exception handling code
}
Puteți avea câte catch
blocuri doriți. Cu toate acestea, un singur catch
bloc nu poate specifica excepții care se moștenesc reciproc. Cu alte cuvinte, nu puteți scrie catch ( Exception
| RuntimeException
e), deoarece RuntimeException
clasa moștenește Exception
.
GO TO FULL VERSION