Programmēšana

Izņēmumi Java, 2. daļa: Papildu funkcijas un veidi

JDK 1.0 ieviesa valodu iezīmju un bibliotēku tipu struktūru, ar ko rīkoties izņēmumiem, kas ir atšķirības no paredzamās programmas uzvedības. Šīs apmācības pirmā puse aptvēra Java pamata izņēmumu apstrādes iespējas. Šajā otrajā pusē ir ieviestas uzlabotas iespējas, ko nodrošina JDK 1.0 un tās turpinātāji: JDK 1.4, JDK 7 un JDK 9. Uzziniet, kā paredzēt un pārvaldīt izņēmumus Java programmās, izmantojot uzlabotas funkcijas, piemēram, kaudzes pēdas, cēloņus un izņēmumu ķēdi, izmēģiniet - ar resursiem, daudzkārtēja nozveja, pēdējais atkārtotais metiens un kaudzes soļošana.

Ņ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.

Izņēmumu apstrāde JDK 1.0 un 1.4: kaudzes pēdas

Katrs JVM pavediens (izpildes ceļš) ir saistīts ar a kaudze tas tiek izveidots, kad tiek izveidots pavediens. Šī datu struktūra ir sadalīta rāmji, kas ir datu struktūras, kas saistītas ar metodes izsaukumiem. Šī iemesla dēļ katra pavediena kaudze bieži tiek dēvēta par a metode-zvana kaudze.

Katru reizi, kad tiek izsaukta metode, tiek izveidots jauns rāmis. Katrā rāmī tiek glabāti vietējie mainīgie, parametru mainīgie (kas satur metodei nodotos argumentus), informācija par atgriešanos pie izsaukšanas metodes, vieta atgriešanās vērtības glabāšanai, informācija, kas noder izņēmuma nosūtīšanai utt.

A kaudzes izsekošana (pazīstams arī kā kaudze atpakaļ izsekot) ir aktīvo kaudzes kadru pārskats noteiktā laika posmā pavediena izpildes laikā. Java Metams klase (klasē) java.lang pakete) nodrošina metodes kaudzes izsekošanas drukāšanai, kaudzes izsekošanas aizpildīšanai un piekļuvei kaudzes izsekošanas elementiem.

Kaudzes pēdas drukāšana

Kad mest paziņojums met metams, tas vispirms meklē piemērotu noķert bloķēt izpildes metodē. Ja tas nav atrasts, tas atsauc metodes izsaukuma kaudzīti, meklējot vistuvāko noķert bloks, kas var apstrādāt izņēmumu. Ja tas nav atrasts, JVM izbeidzas ar piemērotu ziņojumu. Apsveriet 1. sarakstu.

Saraksts 1. PrintStackTraceDemo.java (1. versija)

importēt java.io.IOException; public class PrintStackTraceDemo {public static void main (String [] args) throws IOException {mest jaunu IOException (); }}

Uzskaitot 1. izdomāto piemēru, tiek izveidots a java.io.IOException objektu un izmet šo objektu no galvenais () metodi. Tā kā galvenais () netiek galā ar šo izmetamo un tāpēc galvenais () ir augstākā līmeņa metode, JVM izbeidzas ar piemērotu ziņojumu. Šai lietojumprogrammai tiks parādīts šāds ziņojums:

Izņēmums pavedienā "main" java.io.IOException vietnē PrintStackTraceDemo.main (PrintStackTraceDemo.java:7)

JVM izsūta šo ziņojumu, zvanot Metams's void printStackTrace () metodi, kas izdrukā kaudzes izsekošanu izsaukšanai Metams objekts standarta kļūdu straumē. Pirmajā rindā parādīts metamo numuru izsaukšanas rezultāts toString () metodi. Nākamajā rindā parādīti dati, ko iepriekš reģistrējis fillInStackTrace () (drīzumā apspriests).

Papildu drukas kaudzes izsekošanas metodes

Metamsir pārslogots void printStackTrace (PrintStream ps) un void printStackTrace (PrintWriter pw) metodes izvada kaudzes izsekošanu norādītajai straumei vai rakstītājam.

Steka izsekošana atklāj avota failu un līnijas numuru, kur tika izveidots izmetamais. Šajā gadījumā tas tika izveidots 7. Līnijā PrintStackTrace.java avota fails.

Jūs varat atsaukties printStackTrace () tieši, parasti no a noķert bloķēt. Piemēram, apsveriet otro versiju PrintStackTraceDemo pieteikumu.

2. saraksts. PrintStackTraceDemo.java (2. versija)

importēt java.io.IOException; public class PrintStackTraceDemo {public static void main (String [] args) throws IOException {try {a (); } catch (IOException ioe) {ioe.printStackTrace (); }} static void a () izmet IOException {b (); } static void b () throws IOException {mest jaunu IOException (); }}

2. uzskaitījums atklāj a galvenais () metode, kas izsauc metodi a (), kas izsauc metodi b (). Metode b () met an IOException objekts JVM, kas attin metodi-izsaukuma kaudzi, līdz atrod galvenais ()'s noķert bloks, kas var apstrādāt izņēmumu. Izņēmums tiek veikts, atsaucoties printStackTrace () uz metamo. Šī metode ģenerē šādu izvadi:

java.io.IOException vietnē PrintStackTraceDemo.b (PrintStackTraceDemo.java:24) vietnē PrintStackTraceDemo.a (PrintStackTraceDemo.java:19) vietnē PrintStackTraceDemo.main (PrintStackTraceDemo.java:9)

printStackTrace () neizvada pavediena nosaukumu. Tā vietā tā atsaucas toString () uz mešanas, lai atdotu pilnībā iemetamā klases nosaukumu (java.io.IOException), kas tiek izvadīts pirmajā rindā. Pēc tam tiek izvadīta metodi izsaukuma hierarhija: pēdējā laikā izsauktā metode (b ()) ir augšpusē un galvenais () ir apakšā.

Kādu līniju identificē kaudzes izsekošana?

Steka trase identificē līniju, kurā tiek izveidots izmetams. Tas nenosaka līniju, kur izmetams (via mest), ja vien izmetamais nav iemests tajā pašā līnijā, kur tas ir izveidots.

Steka pēdas aizpildīšana

Metams paziņo a Metams fillInStackTrace () metode, kas aizpilda izpildes kaudzes izsekošanu. Piesaucot Metams objekts, tas reģistrē informāciju par pašreizējā pavediena kaudzes rāmju pašreizējo stāvokli. Apsveriet iespēju norādīt 3. sarakstu.

3. saraksts. FillInStackTraceDemo.java (1. versija)

importēt java.io.IOException; public class FillInStackTraceDemo {public static void main (String [] args) throws IOException {try {a (); } catch (IOException ioe) {ioe.printStackTrace (); System.out.println (); mest (IOException) ioe.fillInStackTrace (); }} static void a () izmet IOException {b (); } static void b () throws IOException {mest jaunu IOException (); }}

Galvenā atšķirība starp 3. un 2. sarakstu ir noķert bloķēt mest (IOException) ioe.fillInStackTrace (); paziņojums, apgalvojums. Šis paziņojums aizstāj ioekaudzes izsekošana, pēc kuras izmetamais tiek atkārtoti izmests. Jums jāievēro šī izeja:

java.io.IOException vietnē FillInStackTraceDemo.b (FillInStackTraceDemo.java:26) vietnē FillInStackTraceDemo.a (FillInStackTraceDemo.java:21) vietnē FillInStackTraceDemo.main (Fill9StackTrack FillInStackTraceDemo.main (FillInStackTraceDemo.java:15)

Tā vietā, lai atkārtotu sākotnējo kaudzes izsekošanu, kas identificē vietu, kur IOException objekts tika izveidots, otrā kaudzes izsekošana atklāj ioe.fillInStackTrace ().

Metamie konstruktori un fillInStackTrace ()

Katrs no Metamsatsaucas konstruktori fillInStackTrace (). Tomēr nākamais konstruktors (ieviests JDK 7) neizmantos šo metodi, kad nokārtosit nepatiesa uz writeableStackTrace:

Izmetams (virknes ziņojums, izmetams cēlonis, Būla iespējošanas nomākšana, loģiskā rakstāmā StackTrace)

fillInStackTrace () izsauc vietējo metodi, kas iet pa pašreizējā pavediena metodi-izsaukuma kaudzīti, lai izveidotu kaudzes izsekošanu. Šī pastaiga ir dārga un var ietekmēt sniegumu, ja tā notiek pārāk bieži.

Ja nokļūstat situācijā (iespējams, iesaistot iegultu ierīci), kur veiktspēja ir kritiska, varat novērst kaudzes izsekošanas izveidošanu, ignorējot fillInStackTrace (). Pārbaudiet 4. sarakstu.

4. saraksts. FillInStackTraceDemo.java (2. versija)

{public static void main (String [] args) throws NoStackTraceException {try {a (); } catch (NoStackTraceException nste) {nste.printStackTrace (); }} static void a () throws NoStackTraceException {b (); } static void b () throws NoStackTraceException {mest jaunu NoStackTraceException (); }} klase NoStackTraceException paplašina izņēmumu {@Override public synchronized Throwable fillInStackTrace () {return this; }}

4. saraksts ievieš NoStackTraceException. Šī pielāgotā pārbaudītā izņēmuma klases ignorēšana fillInStackTrace () Atgriezties šo - atsauce uz atsaukšanos Metams. Šī programma ģenerē šādu izvadi:

NoStackTraceException

Komentējiet svarīgāko fillInStackTrace () metodi, un jūs ievērosiet šādu rezultātu:

NoStackTraceException vietnē FillInStackTraceDemo.b (FillInStackTraceDemo.java:22) vietnē FillInStackTraceDemo.a (FillInStackTraceDemo.java:17) vietnē FillInStackTraceDemo.main (FillInStackTrja

Piekļuve kaudzes izsekošanas elementiem

Dažreiz jums būs jāpiekļūst kaudzes izsekošanas elementiem, lai iegūtu informāciju, kas nepieciešama reģistrēšanai, resursu noplūdes avota identificēšanai un citiem mērķiem. The printStackTrace () un fillInStackTrace () metodes neatbalsta šo uzdevumu, bet ieviests JDK 1.4 java.lang.StackTraceElement un tās metodes šim nolūkam.

The java.lang.StackTraceElement klase apraksta elementu, kas attēlo kaudzes rāmi kaudzes izsekojumā. Tās metodes var izmantot, lai atgrieztu pilnībā kvalificētu klases nosaukumu, kurā ir izpildes punkts, ko pārstāv šis kaudzes mikroelements, kā arī cita noderīga informācija. Šeit ir galvenās metodes:

  • Virkne getClassName () atgriež pilnīgi kvalificētu klases nosaukumu, kurā ir izpildes punkts, ko pārstāv šis kaudzes mikroelements.
  • Virkne getFileName () atgriež avota faila nosaukumu, kurā ir izpildes punkts, ko pārstāv šis kaudzes mikroelements.
  • int getLineNumber () atgriež avota līnijas numuru, kurā ir izpildes punkts, ko pārstāv šis kaudzes mikroelements.
  • Virkne getMethodName () atgriež metodes nosaukumu, kurā ir izpildes punkts, ko pārstāv šis kaudzes mikroelements.
  • boolean isNativeMethod () atgriežas taisnība kad metode, kurā ir izpildes punkts, ko pārstāv šis kaudzes mikroelements, ir vietējā metode.

JDK 1.4 arī ieviesa StackTraceElement [] getStackTrace () metodi java.lang.Thread un Metams klases. Šī metode attiecīgi atgriež kaudzes mikroelementu masīvu, kas attēlo izsaucošā pavediena kaudzes izgāšanu, un nodrošina programmatisku piekļuvi kaudzes izsekošanas informācijai printStackTrace ().

5. saraksts parāda StackTraceElement un getStackTrace ().

5. saraksts. StackTraceElementDemo.java (1. versija)

importēt java.io.IOException; public class StackTraceElementDemo {public static void main (String [] args) throws IOException {try {a (); } catch (IOException ioe) {StackTraceElement [] stackTrace = ioe.getStackTrace (); for (int i = 0; i <stackTrace.length; i ++) {System.err.println ("Izņēmums izmests no" + stackTrace [i] .getMethodName () + "klasē" + stackTrace [i] .getClassName () + "on line" + stackTrace [i] .getLineNumber () + "faila" + stackTrace [i] .getFileName ()); System.err.println (); }}} static void a () izmet IOException {b (); } static void b () throws IOException {mest jaunu IOException (); }}

Palaidot šo lietojumprogrammu, ievērosiet šādu izvadi:

Izņēmums no b klases StackTraceElementDemo faila StackTraceElementDemo.java 33. rindā Izņēmums no klases StackTraceElementDemo klases StackTraceElementDemo.java klases StackTraceElementDemo.java izņēmums no StackTraceElementDemo klases galvenā faila StackTraceElementDemo 9. rindā faila StackTraceElementDemo

Visbeidzot, JDK 1.4 ieviesa setStackTrace () metodi Metams. Šī metode ir paredzēta lietošanai attālās procedūras izsaukuma (RPC) ietvaros un citās uzlabotās sistēmās, ļaujot klientam ignorēt noklusējuma kaudzes izsekošanu, ko ģenerējis fillInStackTrace () kad ir konstruējams metams.

Iepriekš es parādīju, kā ignorēt fillInStackTrace () lai novērstu kaudzes izsekošanu. Tā vietā jūs varētu instalēt jaunu kaudzes izsekošanu, izmantojot StackTraceElement un setStackTrace (). Izveidojiet masīvu StackTraceElement objekti, kas inicializēti, izmantojot šādu konstruktoru, un nodod šo masīvu setStackTrace ():

StackTraceElement (virknes deklarēšanas klase, virknes metodes nosaukums, virknes faila nosaukums, int līnijas numurs)

6. saraksts parāda StackTraceElement un setStackTrace ().

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