Programmēšana

Izņēmumi Java, 1. daļa: Izņēmumu apstrādes pamati

Java izņēmumi ir bibliotēkas veidi un valodas līdzekļi, ko izmanto, lai attēlotu un novērstu programmas kļūmes. Ja esat vēlējies saprast, kā avotā tiek attēlota neveiksme, esat nonācis īstajā vietā. Papildus Java izņēmumu pārskatam es jums sākšu ar Java valodas funkcijām, kas saistītas ar objektu mešanu, koda izmēģināšanu, kas var neizdoties, metamo objektu uztveršanu un Java koda tīrīšanu pēc izņēmuma izmetšanas.

Šīs apmācības pirmajā pusē uzzināsiet par valodas pamatfunkcijām un bibliotēkas tipiem, kas ir bijuši kopš Java 1.0. Otrajā pusē jūs atradīsit uzlabotas iespējas, kas ieviestas jaunākās Java versijās.

Ņemiet vērā, ka šīs apmācības kodu piemēri ir saderīgi ar JDK 12.

lejupielādēt Iegūt kodu Lejupielādējiet šajā apmācībā avota kodu, piemēram, lietojumprogrammām. Izveidoja Jeff Friesen JavaWorld.

Kādi ir Java izņēmumi?

Neveiksme rodas, ja Java programmas parasto darbību pārtrauc negaidīta rīcība. Šī atšķirība ir pazīstama kā izņēmums. Piemēram, programma mēģina atvērt failu, lai lasītu tā saturu, taču fails nepastāv. Java izņēmumus klasificē dažos veidos, tāpēc ņemsim vērā katru no tiem.

Pārbaudīti izņēmumi

Java klasificē izņēmumus, kas rodas no ārējiem faktoriem (piemēram, trūkstoša faila), kā pārbaudīti izņēmumi. Java kompilators pārbauda, ​​vai ir arī šādi izņēmumi apstrādāti (izlaboti), ja tie rodas vai ir dokumentēti apstrādāti citur.

Izņēmumu apstrādātāji

An izņēmumu apstrādātājs ir koda secība, kas apstrādā izņēmumu. Tas izjautā kontekstu - tas nozīmē, ka tas nolasa vērtības, kas saglabātas no mainīgajiem, kuri bija izņēmuma laikā darbības jomā, un pēc tam iemācīto atjauno Java programmu normālas uzvedības plūsmā. Piemēram, izņēmumu apstrādātājs var nolasīt saglabātu faila nosaukumu un pamudināt lietotāju aizstāt trūkstošo failu.

Izpildes laika (nepārbaudīti) izņēmumi

Pieņemsim, ka programma mēģina sadalīt veselu skaitli ar veselu skaitli 0. Šī neiespējamība ilustrē cita veida izņēmumus, proti, a izpildlaika izņēmums. Atšķirībā no pārbaudītajiem izņēmumiem izpildlaika izņēmumi parasti rodas no slikti uzrakstīta avota koda, un tāpēc tie jānosaka programmētājam. Tā kā kompilators nepārbauda, ​​vai izpildlaika izņēmumi tiek apstrādāti vai dokumentēti, lai tos apstrādātu citur, jūs varat domāt par izpildlaika izņēmumu kā nepārbaudīts izņēmums.

Par izpildlaika izņēmumiem

Varat modificēt programmu, lai tā darbotos izpildlaika izņēmuma gadījumā, taču labāk ir labot pirmkodu. Izpildes laika izņēmumi bieži rodas no nederīgu argumentu nodošanas bibliotēkas metodēm; Buggy izsaukuma kods ir jānosaka.

Kļūdas

Daži izņēmumi ir ļoti nopietni, jo tie apdraud programmas spēju turpināt izpildi. Piemēram, programma mēģina piešķirt atmiņu no JVM, taču nav pietiekami daudz brīvas atmiņas, lai apmierinātu pieprasījumu. Vēl viena nopietna situācija rodas, kad programma mēģina ielādēt klases failu, izmantojot Class.forName () metodes izsaukums, bet klases fails ir bojāts. Šāda veida izņēmums ir pazīstams kā kļūda. Nekad nevajadzētu mēģināt pats rīkoties ar kļūdām, jo ​​JVM, iespējams, nespēs no tā atkopties.

Izņēmumi pirmkodā

Izņēmumu pirmkodā var attēlot kā kļūdas kods vai kā objekts. Es iepazīstināšu abus un parādīšu, kāpēc priekšmeti ir pārāki.

Kļūdu kodi pret objektiem

Programmēšanas valodas, piemēram, C, izmanto veselu skaitli kļūdu kodi pārstāvēt neveiksmi un neveiksmes iemeslus - t.i., izņēmumus. Šeit ir pāris piemēri:

if (chdir ("C: \ temp")) printf ("Nevar mainīt uz temp direktoriju:% d \ n", errno); FILE * fp = fopen ("C: \ temp \ foo"); if (fp == NULL) printf ("Nevar atvērt foo:% d \ n", errno);

C chdir () Funkcija (mainīt direktoriju) atgriež veselu skaitli: 0 panākumiem vai -1 neveiksmēm. Līdzīgi arī C fopen () (fails atvērts) funkcija atgriež nulli rādītājs (vesels skaitlis adrese) uz a FILE struktūra uz panākumiem vai nulles (0) rādītājs (ko attēlo konstante NULL) par neveiksmi. Jebkurā gadījumā, lai identificētu izņēmumu, kas izraisīja kļūmi, jums ir jāizlasa vispārīgais errno mainīgā lieluma kļūdas kods uz veselu skaitli.

Kļūdu kodi rada dažas problēmas:

  • Veseli skaitļi ir bezjēdzīgi; tie neapraksta viņu pārstāvētos izņēmumus. Piemēram, ko nozīmē 6?
  • Saistīt kontekstu ar kļūdas kodu ir neērti. Piemēram, jūs varētu vēlēties izdot tā faila nosaukumu, kuru nevarēja atvērt, bet kur jūs glabājat faila nosaukumu?
  • Veseli skaitļi ir patvaļīgi, kas var radīt neskaidrības, lasot pirmkodu. Piemēram, precizējot ja (! chdir ("C: \ temp")) (! apzīmē NĒ), nevis ja (chdir ("C: \ temp")) pārbaudīt neveiksmi ir skaidrāk. Tomēr, lai norādītu uz panākumiem, tika izvēlēts 0, un tā ja (chdir ("C: \ temp")) jānorāda, lai pārbaudītu kļūmi.
  • Kļūdu kodus ir pārāk viegli ignorēt, kas var izraisīt kļūdainu kodu. Piemēram, programmētājs varētu norādīt chdir ("C: \ temp"); un ignorēt ja (fp == NULL) pārbaudīt. Turklāt programmētājam nav jāpārbauda errno. Nepārbaudot kļūmi, programma rīkojas nepareizi, ja kāda no funkcijām atgriež kļūmes indikatoru.

Lai atrisinātu šīs problēmas, Java izmantoja jaunu pieeju izņēmumu apstrādei. Java mēs objektus, kas apraksta izņēmumus, apvienojam ar mehānismu, kura pamatā ir šo objektu mešana un notveršana. Šeit ir dažas priekšrocības, lietojot objektus pret kļūdas kodu, lai apzīmētu izņēmumus:

  • Objektu var izveidot no klases ar jēgpilnu nosaukumu. Piemēram, FileNotFoundException (iekš java.io iepakojums) ir jēgpilnāks par 6.
  • Objekti var saglabāt kontekstu dažādos laukos. Piemēram, objekta laukos varat saglabāt ziņojumu, faila nosaukumu, kuru nevarēja atvērt, jaunāko pozīciju, kurā neizdevās parsēt, un / vai citus vienumus.
  • Jūs neizmantojat ja paziņojumi, lai pārbaudītu neveiksmi. Tā vietā izņēmuma objekti tiek izmesti apstrādātājam, kas ir atdalīts no programmas koda. Tā rezultātā pirmkodu ir vieglāk nolasīt, un tas, visticamāk, nav kļūdains.

Metams un tā apakšklases

Java nodrošina klašu hierarhiju, kas pārstāv dažāda veida izņēmumus. Šīs klases sakņojas java.lang paketes Metams klase, kopā ar tās Izņēmums, RuntimeException, un Kļūda apakšklases.

Metams ir galvenā izlase, kas attiecas uz izņēmumiem. Tikai no Metams un tā apakšklases var izmest (un pēc tam noķert). Šādi objekti ir pazīstami kā metamie.

A Metams objekts ir saistīts ar detalizēts ziņojums kas apraksta izņēmumu. Lai izveidotu a, tiek nodrošināti vairāki konstruktori, ieskaitot tālāk aprakstīto pāri Metams objekts ar detalizētu ziņojumu vai bez tā:

  • Metams () izveido a Metams bez detalizēta ziņojuma. Šis konstruktors ir piemērots situācijām, kad nav konteksta. Piemēram, jūs vēlaties uzzināt tikai to, ka kaudze ir tukša vai pilna.
  • Metams (virknes ziņojums) izveido a Metams ar ziņu kā detalizētu ziņojumu. Šo ziņojumu var nosūtīt lietotājam un / vai reģistrēt.

Metams nodrošina Virkne getMessage () metode, lai atgrieztu detalizēto ziņojumu. Tas arī nodrošina papildu noderīgas metodes, kuras es iepazīstināšu vēlāk.

Izņēmuma klase

Metams ir divas tiešas apakšklases. Viena no šīm apakšklasēm ir Izņēmums, kas apraksta izņēmumu, kas izriet no ārēja faktora (piemēram, mēģinājums nolasīt no neeksistējoša faila). Izņēmums deklarē tos pašus konstruktorus (ar identiskiem parametru sarakstiem) kā Metams, un katrs konstruktors to izsauc Metams kolēģis. Izņēmums manto Metamsmetodes; tā nedeklarē jaunas metodes.

Java nodrošina daudzas izņēmumu klases, kas tieši apakšklasē Izņēmums. Šeit ir trīs piemēri:

  • CloneNotSupportedException signalizē par mēģinājumu klonēt objektu, kura klase neievieš Klonējams interfeiss. Abi veidi ir java.lang iepakojums.
  • IOException signalizē, ka ir notikusi kāda veida I / O kļūme. Šis tips atrodas java.io iepakojums.
  • ParseException norāda, ka, analizējot tekstu, ir notikusi kļūda. Šis tips ir atrodams java.text iepakojums.

Ievērojiet, ka katrs Izņēmums apakšklases nosaukums beidzas ar vārdu Izņēmums. Šī konvencija ļauj viegli noteikt klases mērķi.

Jums parasti būs apakšklase Izņēmums (vai kādu no tās apakšklasēm) ar savām izņēmuma klasēm (kuru nosaukumiem vajadzētu beigties ar Izņēmums). Šeit ir pāris pielāgotu apakšklases piemēru:

publiskā klase StackFullException paplašina izņēmumu {} public class EmptyDirectoryException paplašina izņēmumu {private String directoryName; public EmptyDirectoryException (virknes ziņojums, virknes direktorijas nosaukums) {super (ziņojums); this.directoryName = direktorijaNosaukums; } public String getDirectoryName () {return direktorijaNosaukums; }}

Pirmajā piemērā aprakstīta izņēmuma klase, kurai nav nepieciešams detalizēts ziņojums. Tas noklusējuma noargument konstruktors izsauc Izņēmums (), kas piesauc Metams ().

Otrais piemērs apraksta izņēmuma klasi, kuras konstruktoram ir nepieciešams detalizēts ziņojums un tukšā direktorija nosaukums. Konstruktors piesauc Izņēmums (virknes ziņojums), kas piesauc Metams (virknes ziņojums).

Objekti, kas izveidoti no Izņēmums vai kāda no tās apakšklasēm (izņemot RuntimeException vai kādu no tās apakšklasēm) pārbauda izņēmumus.

RuntimeException klase

Izņēmums ir tieši apakškategorija RuntimeException, kas apraksta izņēmumu, kas, visticamāk, rodas slikti uzrakstīta koda dēļ. RuntimeException deklarē tos pašus konstruktorus (ar identiskiem parametru sarakstiem) kā Izņēmums, un katrs konstruktors to izsauc Izņēmums kolēģis. RuntimeException manto Metamsmetodes. Tā nedeklarē jaunas metodes.

Java nodrošina daudzas izņēmumu klases, kas tieši apakšklasē RuntimeException. Visi piemēri ir java.lang iepakojums:

  • Aritmētiskais izņēmums signalizē par nelikumīgu aritmētisko darbību, piemēram, mēģinājumu sadalīt veselu skaitli ar 0.
  • NelegālsArgumentException signalizē, ka metodei ir nodots nelikumīgs vai nepiemērots arguments.
  • NullPointerException signalizē par mēģinājumu izsaukt metodi vai piekļūt instances laukam, izmantojot nulles atsauci.

Objekti, kas izveidoti no RuntimeException vai viena no tās apakšklasēm ir nepārbaudīti izņēmumi.

Kļūdu klase

Metamscita tiešā apakšklase ir Kļūda, kas apraksta nopietnu (pat nenormālu) problēmu, kuru saprātīgai lietojumprogrammai nevajadzētu mēģināt risināt - piemēram, atmiņas trūkums, JVM kaudzes pārpildīšana vai mēģinājums ielādēt klasi, kuru nevar atrast. Patīk Izņēmums, Kļūda deklarē identiskus konstruktorus Metams, manto Metamsmetodes un nedeklarē nevienu no savām metodēm.

Jūs varat identificēt Kļūda apakšklases no konvencijas, ar kuru beidzas viņu klases nosaukumi Kļūda. Piemēri ietver OutOfMemoryError, LinkageError, un StackOverflowError. Visi trīs veidi pieder pie java.lang iepakojums.

Mest izņēmumi

C bibliotēkas funkcija paziņo izsaukuma kodam par izņēmumu, iestatot globālo errno mainīgais kļūdas kods un atgriešanās kļūmes kods. Turpretī Java metode izmet objektu. Zināšanas par to, kā un kad mest izņēmumus, ir būtisks efektīvas Java programmēšanas aspekts. Izņēmums ir saistīts ar diviem galvenajiem soļiem:

  1. Izmantojiet mest paziņojums mest izņēmuma objektu.
  2. Izmantojiet metieni klauzulu, lai informētu sastādītāju.

Vēlākajās sadaļās galvenā uzmanība tiks pievērsta izņēmumu uztveršanai un tīrīšanai pēc tiem, bet vispirms uzzināsim vairāk par metamajiem priekšmetiem.

Metiena paziņojums

Java nodrošina mest paziņojums mest objektu, kas apraksta izņēmumu. Šeit ir sintakse mest paziņojums, apgalvojums :

mest izmetams;

Objekts, ko identificējis izmetams ir Metams vai kādu no tā apakšklasēm. Tomēr jūs parasti izmetat tikai objektus, kas izveidoti no apakšklasēm Izņēmums vai RuntimeException. Šeit ir pāris piemēri:

mest jaunu FileNotFoundException ("nevar atrast failu" + faila nosaukums); mest jaunu IllegalArgumentException ("skaitlim nodotais arguments ir mazāks par nulli");

Metamais tiek izmests no pašreizējās metodes JVM, kas pārbauda, ​​vai šai metodei ir piemērots hendlers. Ja tas nav atrasts, JVM atvieno metodi-izsaukuma kaudzīti, meklējot tuvāko izsaukšanas metodi, kas var apstrādāt izmetamā aprakstīto izņēmumu. Ja tā atrod šo metodi, tā nodod metamo metodes apstrādātājam, kura kods tiek izpildīts, lai apstrādātu izņēmumu. Ja nav atrasta metode izņēmuma apstrādei, JVM tiek pārtraukts ar piemērotu ziņojumu.

Metienu klauzula

Jums jāinformē kompilators, kad metot pārbaudītu izņēmumu no metodes. Dariet to, pievienojot a metieni klauzula metodes galvenei. Šai klauzulai ir šāda sintakse:

metieni pārbaudītsExceptionClassName (, pārbaudītsExceptionClassName)*

A metieni klauzula sastāv no atslēgas vārda metieni kam seko komatu atdalīts saraksts ar pārbaudītajiem izņēmumiem, kas izmesti no metodes. Šeit ir piemērs:

public static void main (String [] args) izmet ClassNotFoundException {if (args.length! = 1) {System.err.println ("use: java ... classfile"); atgriešanās; } Class.forName (argumenti [0]); }

Šis piemērs mēģina ielādēt klases failu, kas identificēts ar komandrindas argumentu. Ja Class.forName () nevar atrast klases failu, tas iemet a java.lang.ClassNotFoundException objekts, kas ir pārbaudīts izņēmums.

Pārbaudīts izņēmuma strīds

The metieni klauzula un pārbaudītie izņēmumi ir pretrunīgi. Daudzi izstrādātāji ienīst spiešanu norādīt metieni vai rīkojieties ar pārbaudīto (-ajiem) izņēmumu (-iem). Uzziniet vairāk par to sadaļā Vai pārbaudītie izņēmumi ir labi vai slikti? emuāra ziņa.

$config[zx-auto] not found$config[zx-overlay] not found