Sunteți pe pagina 1din 31

Cuvinte importante:

-determinarea clasei unui obiect: utilizarea operatorului de cast; utilizarea unui obiect de tip class, metoda getname(); utilizarea operatorului instanceof; - determinarea superclasei sau a interfetei unui obiect: metoda getsuperclass(); metoda getinterfaces(); - tratarea erorilor: exceptii Java; ierarhia de exceptii predefinite de platforma Java; verificarea consistentei exceptiilor Java; - interceptarea (prinderea) si tratarea exceptiilor in cadrul aceleiasi metode: blocul try catch; - declararea metodelor care pot semnala (arunca) exceptii catre alte metode: clauza throws; - crearea si semnalarea propriilor exceptii: definirea propriilor clase de exceptii; semnalarea (aruncarea) propriilor exceptii; instructiunea throw; - cum sa folosim exceptiile?
11/16/2013 1

Determinarea clasei unui obiect


In Java, determinarea clasei unui obiect se poate realiza in mai multe modalitati:
- utilizand operatorul de cast; - utilizand un obiect de tip Class; - utilizand operatorul instanceof. Utilizarea operatorului de cast pentru determinarea clasei unui obiect Am invatat in lectia 7 ca operatorul de cast este un operator unar prin care un obiect de tipul unei clase este convertit la un alt tip corespunzator altei clase, in mod explicit.

Daca operatia de cast este incorecta (daca obiectul nu poate fi convertit la tipul specificat) atunci va fi semnalata o exceptie (eroare) de tipul ClassCastException.
De exemplu, urmatoarea secventa de cod, semnaleaza o exceptie de tipul ClassCastException:

Object x = new Integer(12); System.out.println((String)x);


In acest exemplu, variabila x pastreaza o referinta catre un obiect al clasei Integer care nu se afla in ierarhia de clase Java pe aceeasi ramura cu clasa String.
11/16/2013 2

Utilizarea unui obiect de tip Class Un obiect de tip Class este o instanta a clasei Class, existenta in pachetul java.lang. Uneori clasa Class mai este denumita si metaclasa. Masina virtuala Java ataseaza fiecarei clase, existente intr-un program, un obiect de tipul Class, care este utilizat cand se creaza instante ale clasei respective. Acest obiect de tip Class poate fi utilizat si de programator pentru a afla informatii despre o clasa oarecare folosita in program. O posibilitate de obtinere a unui obiect de tip Class asociat unei clase este de a crea o instanta a clasei respective care sa foloseasca metoda getClass() a clasei Object (acesta metoda poate fi folosita de clasa respectiva pentru ca orice clasa creata deiveaza din clasa Object).

Metoda getClass() returneaza un obiect de tip Class care reprezinta clasa din care face parte obiectul respectiv (referit printr-o variabila referinta).
De exemplu: AnimalDeCasa a = new Pisica(); Class clasa = a.getClass(); Dupa obtinerea obiectului de tip Class atasat clasei pentru care se doreste obtinerea unor informatii se pot apela metode ale clasei Class pentru a obtine informatiile dorite.
11/16/2013 3

O metoda des folosita din clasa Class este getName() care permite obtinerea numelui unei clase. De exemplu, se poate folosi urmatorul apel al metodei getName() pentru aflarea numelui clasei din care face parte instanta referita cu numele a, in exemplul anterior: String numeClasa = clasa.getName();

Metodele getClass() si getName() pot fi apelate in aceeasi instructiune, ca in exemplul urmator:


String numeClasa = a.getClass().getName(); Utilizarea operatorului instanceof

Operatorul instanceof da posibilitatea verificarii daca un obiect este instanta a unei clase specificate.
Acesta are doi operanzi, un obiect in stanga si un nume de clasa in dreapta, ca in expresia de mai jos:

<nume_obiect> instanceof <nume_clasa>


Expresia poate lua valoarea true sa false in functie de apartenenta sau neapartenenta obiectului la clasa cu numele <nume_clasa> sau la oricare dintre subclasele sale.
11/16/2013 4

Iata un exemplu de utilizare a operatorului instanceof pentru un obiect referit cu variabila a pentru a determina daca el este o instanta a clasei Pisica sau a clasei Caine: AnimalDeCasa a = new Caine();

if (a instanceof Pisica)
System.out.println("Animalul acesta de casa este o pisica."); else System.out.println("Animalul acesta de casa este un caine."); Rezultatul executiei acestei secvente de cod este: Animalul acesta de casa este un caine. Operatorul instanceof poate fi folosit si pentru interfete. Daca un obiect implementeaza o interfata, operatorul instanceof cu numele interfetei respective in partea dreapta va returna valoarea true.

11/16/2013

Determinarea superclasei sau a interfetei unui obiect


Din clasa Class mai pot fi folosite alte doua metode pentru aflarea superclasei unui obiect si a interfetei pe care o implementeaza clasa obiectului, si anume: metoda getSuperclass() si metoda getInterfaces(). Metoda getSuperclass() din clasa Class returneaza un obiect de tip Class care reprezinta superclasa clasei obiectului respectiv. Pentru a realiza un apel corect al metodei trebuie mai intai sa se obtina un obiect de tip Class al clasei obiectului. De exemplu, se poate folosi urmatorul apel al metodei getSuperclass() pentru aflarea numelui superclasei din care face parte instanta referita cu numele a: AnimalDeCasa a = new Pisica(); String numeSuperclasa = a.getClass().getSuperclass().getName(); a = new Caine(); numeSuperclasa = a.getClass().getSuperclass().getName();

11/16/2013

Metoda getInterfaces() din clasa Class returneaza un tablou de obiecte de tip Class care reprezinta toate interfetele implementate de clasa obiectului respectiv. Ordinea in care se stocheza in tabou obiectele care reprezinta interfetele clasei este data de ordinea in care ele au fost declarate in instructiunea de declarare a clasei obiectului. Daca clasa obiectului respectiv nu implementeaza o interfata, atunci metoda returneaza un tablou de obiecte de tip Class de lungime 0. Pentru a realiza un apel corect al metodei trebuie mai intai sa se obtina un obiect de tip Class al clasei obiectului. De exemplu, se poate folosi urmatorul apel al metodei getInterfaces() pentru aflarea numelor interfetelor pe care le implementeaza clasa din care face parte instanta referita cu numele a: Class [] interfata = a.getClass().getInterfaces(); if (interfata.length == 0) System.out.println("Clasa " + numeClasa + " nu implementeaza o interfata"); else { String numeInterfata = interfata [0].getName(); System.out.println("Numele interfetei este: " + numeInterfata); }
11/16/2013 7

Tratarea erorilor
Erorile care apar in faza de executie a unei aplicatii informatice sunt produse din diverse cauze cum ar fi: - programatorul nu a anticipat toate situatiile posibile in care ar putea ajunge aplicatia informatica; - existenta unor situatii aflate in afara controlului programatorului (date eronate primite de la utilizatori, fisiere care nu mai contin date corecte, dispozitive hardware care nu mai functioneaza etc). Exceptii Java

In Java, exceptiile sunt evenimente anormale care au loc in timpul executiei unei aplicatii si care pot duce la intreruperea executiei normale a acesteia.
Atunci cand aplicatia informatica isi interupe executia normala, inseamna ca a fost semnalata (thrown - aruncata) o exceptie. Faptul ca o exceptie a fost semnalata inseamna, in Java, ca a aparut o eroare. Exceptiile pot fi semnalate, implicit, de sistem sau, explicit, de aplicatia informatica realizata.
11/16/2013 8

Exceptia poate fi si interceptata (caught - prinsa). Interceptarea unei exceptii inseamna tratarea situatiilor speciale (erorilor) astfel incat aplicatia informatica proiectata sa nu se mai termine anormal. Ierarhia de exceptii predefinite de platforma Java In Java, exceptiile sunt instante ale unor clase derivate din clasa Throwable. Clasa Throwable, definita in pachetul java.lang, reprezinta clasa de baza pentru intreaga familie de clase de exceptii. Cand se semnaleaza (este aruncata) o exceptie este creata o instanta a unei clase de exceptii. Figura de mai jos ilustreaza ierarhia claselor de exceptii, pornind de la clasa de baza Throwable si continuand cu cateva dintre subclasele cele mai importante. Object Throwable Exception RuntimeException ArithmeticException
11/16/2013

Error IOException
9

ClassCastException

Clasa Throwable are doua subclase directe: - Error; - Exception. Clasa Error, impreuna cu toate clasele derivate din ea, descrie exceptii grave, numite erori. Aceste erori sunt rare si, de obicei, fatale. In general,ele nu pot fi interceptate de catre aplicatia informatica in care s-au produs si determina intreruperea executiei programului (de exemplu, OutOfMemoryError). Java este cea care foloseste acest tip de erori daca are nevoie de ele. Clasa Exception, impreuna cu toate clasele derivate din ea, reprezinta exceptiile propriu-zise Java. Exceptiile semnalate descriu conditii anormale, care sunt, de cele mai mute ori, tratate de aplicatie, desi sunt anumite exceptii care nu pot fi tratate si atunci aplicatia va fi oprita din executie. Clasa Exception are multe subclase definite in cadrul pachetului java.lang. Aceste subclase indica diverse tipuri de exceptii care pot aparea in cadrul unei aplicatii Java. De exemplu, tipul de exceptie NoSuchFieldException semnaleaza ca programul a incercat sa foloseasca o variabila de instanta sau de clasa care nu exista.
11/16/2013 10

Clasa RuntimeException este foarte des folosita de programatori, deoarece ea este clasa de baza pentru exceptiile care apar in timpul executiei unui program. De exemplu, tipul de exceptie ClassCastException (prezentat la inceputul acestei lectii) indica faptul ca aplicatia noastra a incercat sa faca o conversie explicita de tip pentru un obiect ce nu poate fi convertit la tipul specificat. Nu toate exceptiile sunt definite in pahetul java.lang. De exemplu, toate exceptiile I/O (de intrare/iesire) sunt derivate din clasa java.io.IOException si sunt definite in pachetul java.io. Verificarea consistentei exceptiilor Java In Java, o metoda poate indica tipurile de exceptii pe care le poate semnala (arunca). Compilatorul Java cat si masina virtuala Java verifica daca aceste exceptii aruncate in cadrul unei metode sunt fie tratate in cadrul acelei metode, fie specificate ca fiind aruncate de metoda respectiva la alte metode in care urmeaza a fi tratate. Aceste tipuri de exceptii se numesc exceptii verificate. De exemplu, metodele care ciresc din fisiere sau de la tastatura pot arunca exceptii de tipul IOException. Atunci cand se folosesc aceste metode in aplicatia Java, programatorul trebuie sa aiba grija sa intercepteze (sa prinda) si sa trateze exceptiile de tipul IOException.Compilatorul este cel care il obliga pe programator sa intercepteze si sa trateze exceptiile de tipul IOException.
11/16/2013 11

In cazul exceptiilor neverificate de catre compilator, programatorul poate decide daca prinde (semnaleaza) si trateaza exceptia sau trece cu vederea exceptia. Exceptiile verificate sunt toate tipurile de exceptii derivate din clasa Exception (inclusiv clasa Exception), mai putin clasa RuntimeException si subclasele ei. Exceptiile neverificate sunt de tipul clasei Throwable, de tipul clasei Error si al subclaselor ei, precum si de tipul clasei RuntimeException si al subclaselor ei.

Interceptarea (prinderea) si tratarea exceptiilor in cadrul aceleiasi metode


In fiecare situatie de exceptie exista doua parti: - partea care semnaleaza exceptia si - partea care o intercepteaza si o trateaza. O exceptie poate fi aruncata de la o metoda la alta de mai multe ori inainte de a fi interceptata, insa pana la urma ea va fi interceptata si tratata.

Pentru a intercepta si trata o exceptie trebuie parcursi doi pasi:


- gruparea codului care contine metoda ce poate semnala (arunca) exceptia in cadrul unui bloc try;
11/16/2013

- interceptarea si tratarea exceptiei in cadrul unui bloc catch.

12

Operatiile try (incearca) si catch (intercepteaza) inseamna, de fapt: Incearca aceasta portiune de cod, care poate cauza o exceptie. Daca se executa cu succes, continua aplicatia. Daca nu, intercepteaza exceptia si trateaz-o. Un bloc try este de forma:

try
{ //apeluri de metode care pot genera exceptii <instructiuni>;

}
Blocul try contine instructiuni care sunt incercate a fi executate, urmand ca, in cazul in care ele nu se pot executa cu succes, eroarea sa fie interceptata si tratata in blocul catch. Daca instructiunile se pot executa cu succes, aplicatia se va executa normal fara a tine cont de partea de tratare a exceptiilor din blocul catch.

Nota: Unui bloc de instructiuni try i se asociaza in mod obligatoriu unul sau mai multe blocuri catch.

11/16/2013

13

Blocurile catch de instructiuni sunt asociate cu un bloc try astfel: try { } catch () { } catch () { }

11/16/2013

14

Forma generala a unui bloc catch este: catch(<nume_clasa_de_exceptii> <nume_variabila>) unde: - <nume_clasa_de_exceptii> - specifica tipul de exceptie care poate fi tratat, tip dat de numele clasei de exceptie; - <nume_variabila> - specifica numele prin care poate fi referita instanta ce reprezinta exceptia tratata de blocul catch; aceasta variabila este recunoscuta si poate fi folosita doar in cadrul blocului catch.

Instructiunile din blocul catch se executa doar daca instructiunile din blocul try genereaza exceptii si aceste exceptii sunt instante ale clasei cu numele <nume_clasa_de exceptii> precizat in antetul instructiunii catch.
Dupa ce exceptia a fost tratata, se executa in continuare urmatoarea linie de cod aflata dupa secventa catch.

11/16/2013

15

Urmatorul exemplu (cireste un sir de caractere si incearca, intr-un bloc try, sa il converteasca la un numar intreg. In caz de nereusita, se intercepteaza, in blocul catch, o exceptie de tip NumberFormatException, care este aruncata de metoda Integer.parseInt() atunci cand numarul introdus nu este un numar intreg. Tratarea acestui tip de eroare se face printr-un mesaj de avertizare si returnarea valorii implicite 0 pentru un numar intreg. De asemenea, atunci cand se incearca citirea sirului de caractere de la tastatura, intr-un bloc tray, se pot intercepta, intr-un bloc catch, eventualele exceptii de tip IOException, care sunt aruncate de metoda readLine(). Tratarea acestui tip de eroare se face prin returnarea valorii implicite null pentru un String.
package intrareiesire; import java.io.*; /* cieste un sir de caractere si incerca sa il converteasca la tipul int */ public class CitesteDate { public static String citesteString() { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); try { return br.readLine(); } catch(IOException ioe) { return null; } }
11/16/2013 16

public static int citesteNrInt() { try { return Integer.parseInt(citesteString()); } catch(NumberFormatException nfe) { System.out.println("Nu este numar intreg."); return 0; } } }

Programul urmator (TestCiesteNumere.java) apeleaza metodele din clasa CitesteDate, (care semnaleaza, intercepteaza si trateaza erorile care apar in cadrul lor) pentru a citi un sir de numere de tastatura.
import intrareiesire.*; class TestCitesteNumere { public static void main(String[] args) { citesteDate valIntreg = new citesteDate(); System.out.println("Introduceti numarul de elemente ale sirului:"); int n = valIntreg.citesteNrInt(); int [] numere = new int [n]; System.out.println ("Introduceti elementele sirului: "); for (int i = 0; i < numere.length; i++) numere [i] = valIntreg.citesteNrInt(); System.out.println ("Sirul de numere introdus este: "); for (int i = 0; i < numere.length; i++) System.out.print(numere[i] + " "); }}
11/16/2013 17

Exemplul, descris mai sus, prezinta modul de interceptare a unui anumit tip de exceptie. Deoarece clasele de exceptii sunt organizate ierarhic, nu este necesar ca tipul de exceptie tratat de blocul catch si tipul de exceptie aruncat de o metoda din blocul try sa fie identice. Un bloc catch, care trateaza un tip de exceptii va intercepta si trata si clasele de exceptii derivate din exceptia respectiva. In exemplul de fata, se poate intercepta in blocul catch, exceptia creata de tipul NumberFormatException, folosind clasa Exception care este superclasa pentru NumberFormatException. Astfel, codul ar putea arata astfel:
public static int citesteNrInt()

{
try { return Integer.parseInt(citesteString()); } catch(Exception nfe) { System.out.println("Nu este numar intreg."); return 0; } } }

11/16/2013

18

In aceasta situatie, blocul catch intercepteaza toate exceptiile Exception, dar si clase de exceptii derivate din clasa Exception, cum este si cazul clasei de exceptii FormatNumberException. Se prefera totusi, utilizarea blocurilor catch specializate, care ofera mai multe detalii despre situatia de eroare, si nu a celor generale. Nota: Toate clasele de exceptii mostenesc de la clasa Throwable cateva metode utile pentru aflarea de informatii despre situatia de eroare. O folosire uzuala are metoda getMessage(). Ea afiseaza un mesaj detaliat referitor la ce s-a intamplat. Daca se doreste interceptarea si tratarea, in blocul catch, a unor tipuri foarte diferite de exceptii semnalate in blocul try, care nu sunt inrudite prin mostenire, atunci se asocieaza blocului try mai multe blocuri catch. Blocurile catch sunt examinate in ordinea in care ele apar in fisierul sursa. In timpul procesului de examinare, primul bloc catch care va corespunde exceptiei semnalate va fi executat, iar celelalte ignorate.

11/16/2013

19

Declararea metodelor care pot semnala (arunca) exceptii catre alte metode (transmiterea exceptiilor catre baza stivei de apel)
In paragraful anterior, am descris cazul in care exceptiile sunt interceptate (prinse) si tratate in cadrul aceleiasi metode, nefiind transmise altor metode care apeleaza metoda respectiva. A doua posibilitate este aceea de a specifica exceptiile care nu sunt tratate in cadrul metodei respective, fiind semnalate (aruncate) mai departe catre alte metode care le vor intercepta (prinde) si le vor trata. Atunci cand programatorul decide ca o metoda, din aplicatia informatica, sa nu intercepteze o anumita exceptie care poate fi semnalata de codul din interiorul ei, trebuie sa se precizeze ca metoda respectiva poate semnala (arunca) la randul ei exceptia respectiva catre alte metode care o apeleaza. Pentru a indica faptul ca o metoda poate semnala (arunca) o exceptie, catre alte metode care o apeleaza, se foloseste in antetul metodei respective clauza throws in care se specifica numele exceptiilor pe care le poate semnala (arunca) metoda respectiva.

11/16/2013

20

Observatii: 1. Exceptiile specificate in clauza throws nu trebuie sa fie interceptate (prinse) si tratate in cadrul metodei respective care foloseste clauza throws. 2.Semnalarea (aruncarea) exceptiilor incepe cu metoda originala care daca nu intercepteaza si nu trateaza exceptiile generate, le semnaleaza (le arunca) mai departe metodei care o apeleaza, care la randul ei daca nu le intercepteaza si nu trateaza le semnaleaza (le arunca) mai departe unei alte metode care o apeleaza pe aceasta din urma si asa mai departe. In final exceptia va trebui interceptata (prinsa) si tratata in cadrul unei metode. Astfel, masina virtuala Java cauta in stiva de apel metoda care intercepteaza si trateaza exceptia, pornind de la metoda in care a aparut exceptia, deci dinspre varful stivei spre baza stivei. Forma antetului metodei care specifica tipurile de exceptii semnalate (aruncate) de metoda este: [<modificatori_acces>] [<modificatori_metoda>] <tip_returnat> <nume_metoda> ([<param1>, <param2>, ]) throws <nume_clasa_de_exceptii1>[, <nume_clasa_de_exceptii2>, ]

11/16/2013

21

Nota: Specificarea prin clauza throws a exceptiilor aruncate de metoda originala nu se poate omite, daca metoda respectiva genereaza exceptii pe care nu le trateaza, deoarece compilatorul detecteaza aceasta scapare si o raporteaza ca eroare de compilare, propunand doua solutii: tratarea lor in cadrul metodei (prin blocuri trycatch) sau specificarea lor in clauza throws. Exemplul prezentat anterior, al clasei CitesteDate, poate fi modificat astfel incat exceptiile de tipul IOException care sunt semnalate (aruncate) in metoda citesteString (), de catre metoda readLine(), sa fie semnalate (aruncate) mai departe in metoda citesteNrInt(), care apoi sa le semnaleaza metodei main() din clasa TestCitesteNumereThrows (care reprezinta aplicatia Java). Astfel, s-a creat o noua clasa CitesteDateThrows care are definitia:
package intrareiesire; import java.io.*; /* cieste un sir de caractere si incerca sa il converteasca la tipul int */ public class CitesteDateThrows { public static String citesteString() throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); return br.readLine(); }
11/16/2013 22

public static int citesteNrInt() throws IOException { try { return Integer.parseInt(citesteString()); } catch(NumberFormatException nfe) { System.out.println("Nu este numar intreg."); return 0; } } }

Clasa TestCitesteNumereThrows (care reprezinta programul principal) are definitia data de secventa de cod:
import intrareiesire.*; import java.io.*; class TestCitesteNumereThrows { public static void main(String[] args) throws IOException { CitesteDateThrows valIntreg = new CitesteDateThrows(); System.out.println("Introduceti numarul de elemente ale sirului:"); int n = valIntreg.citesteNrInt();
11/16/2013 23

int [] numere = new int [n]; System.out.println ("Introduceti elementele sirului: "); for (int i = 0; i < numere.length; i++) numere [i] = valIntreg.citesteNrInt(); System.out.println ("Sirul de numere introdus este: "); for (int i = 0; i < numere.length; i++) System.out.print(numere[i] + " "); } }

Crearea si semnalarea propriilor exceptii


Pe langa exceptiile definite de platforma Java, programatorul poate defini propriile clase de exceptii. Aceste clase proprii de exceptii descriu situatii de exceptii particulare aplicatiei respective care nu exista in ierarhia de clase de exceptii oferita de platforma Java. Clasele proprii de exceptii sunt derivate (direct sau indirect) din clasa Throwable. De regula, se creaza propriile clase de exceptii derivate din clasa Exception. Nota: In definirea noilor clase de exceptii, se recomanda adaugarea la numele clasei a sufixului Exception, pentru toate clasele derivate (direct sau indirect) din clasa Exception (de exemplu, MyNewException).
11/16/2013 24

Clasele proprii de exceptii sunt clase Java obisnuite. Clasele proprii de exceptii poseda, de obicei, doi constructori: - primul constructor nu primeste nici un parametru; - al doilea constructor primeste ca parametru un sir de caractere care reprezinta un mesaj ce evidentiaza situatia de eroare.

Definirea propriilor clase de exceptii


De regula, o clasa proprie de exceptii este definita ca in exemplul de mai jos:
package exceptii; public class IndexException extends Exception { public IndexException() { super(); } public IndexException(String msg) { super(msg); } }
11/16/2013 25

Clasa IndexException definita mai sus nu aduce practic nimic nou clasei Exception, deoarece defineste doar doi constructori care apeleaza constructorii superclasei Exception. Totusi, tipul exceptiei in sine este important pentru ca ajuta programatorul sa intercepteze tip respectiv de exceptie atunci cand este necesar.
Semnalarea (aruncarea) propriilor exceptii

Sa ne reamintim ca, toate exceptiile sunt instante ale unei clase de exceptie oarecare, definite fie in biblioteca Java standard, fie de programator.
Pentru a semnala (arunca) un tip de exceptie definita de programator, trebuie sa se creeze, mai intai, o instanta a sa.

Folosind definirea de clasa de exceptie prezentata, crearea unei instante a clasei de excepie IndexException poate fi facuta in doua moduri:
new IndexException(); new IndexException("Stiva vida. ");

In cel de al doilea caz situatia de eroare transmite si o informatie, sub forma mesajului Stiva vida., care poate fi folosit de codul care trateaza exceptia aparuta pentru a afisa un mesaj informativ.
11/16/2013 26

Odata creata o instanta a unei clase proprii de exceptii, aceasta devine o exceptie Java si este semnalata (aruncata) folosind instructiunea throw.
Instructiunea throw are un singur argument, care trebuie sa fie o instanta a unei clase de exceptii derivate din clasa Exception. Forma instructiunii throw este: throw <instanta_clasa_de_exceptii>; De exemplu, pentru semnalarea (aruncarea) unei exceptii din metoda topAndPop() (exceptie care poate fi generata cand o stiva este vida) se poate folosi urmatoarea secventa de cod: public Object topAndPop() throws IndexException { if (isEmpty()) { throw new IndexException("Stiva vida. "); } return elemStiva[pozitieVarf--]; }
11/16/2013 27

Pentru transmiterea exceptiei semnalate (aruncate) in metoda topAndPop(), cu ajutorul instructiunea throw, catre o alta metoda apelanta se foloseste clauza throws in antetul metodei topAndPop(). In metoda apelanta exceptia IndexException se poate, eventual intercepta (prinde) si trata sau poate fi transmisa mai departe la o alta metoda apelanta. In exemplul prezentatat, interceptarea si tratarea exceptiei de tip IndexException este realizata in metoda main() a aplicatiei (clasa TestStiva1). Iata codul-sursa in care se realizeaza acest lucru:
/* Clasa de test simpla pentru o stiva, care adauga 10 numere * dupa care le extrage in ordine inversa */ import clasegenerice.*; import exceptii.*; public class TestStiva1 { public static void main(String[] args) { Stiva1 s = new StivaArr(10);

//introducem elemente in stiva for (int i = 0; i < 10; i++) { s.push(new Integer(i)); }
11/16/2013 28

//scoatem elementele din stiva si le afisam System.out.print("Continutul stivei este: "); try { while (true) { System.out.print(s.topAndPop() + " "); } } catch(IndexException ie) { System.out.println(); System.out.print("Eroare: " + ie.getMessage()); }
} }

Observatie: In secveta de mai sus, iesirea din bucla while se realizeaza in momentul in care stiva devine vida si metoda topAndPop() semnaleaza (arunca) exceptia IndexException care este interceptata si tratata in blocul catch.

11/16/2013

29

Concluzii privind folosirea eficienta a exceptiilor


Cum sa folosim exceptiile?
1. Daca o metoda din aplicatia Java apeleaza o alta metoda in care s-a folosit clauza throws, avem trei posibilitati: - se trateaza exceptia folosind blocurile try si catch; - se transmite exceptia mai departe pe lant (spre baza stivei de apel), adaugand in metoda respectiva clauza throws; - se realizeaza ambele metode descrise mai sus, atat pentru a intercepta (prinde) si trata exceptia folosind blocurile try catch, cat si pentru a o resemnala explicit folosind instructiunea throw. 2. Daca o metoda din aplicatia Java semnaleaza (arunca) propriile exceptii, aceasta metoda trebuie sa fie declarata folosind clauza throws. De asemenea, exceptia trebuie semnalata explicit in corpul metodei, folosind instructiunea throw. 3. Daca metoda din aplicatia Java suprascrie metoda unei subclase care contine clauza throws, atunci se pot semnala numai aceleasi tipuri de exceptii sau subclase ale exceptiilor respective; nu se pot semnala alte tipuri de exceptii.

11/16/2013

30

Modul incorect de folosire a exceptiilor 1. Sistemul de exceptii al Java a fost proiectat in asa fel incat, daca apare o eroare, sa fim avertizati in legatura cu aceasta. Ignorarea acestor avertismente si nerespectarea lor duce la posibila aparitie a unor erori fatale in cadrul aplicatiilor. Mai mult, folosirea de clauze throws in propriile metode in scopul de a evita tratarea exceptiilor face ca utilizatorii acestor metode (adica obiectele aflate mai sus pe lantul de apeluri) sa fie nevoiti sa le trateze. Astfel metodele noastre se complica nejustificat. Erorile semnalate de compilator cu privire la exceptii au rolul de a ne atrage atentia asupra acestor probleme. 2. Ca regula generala, nu este recomandata utilizarea exceptiilor in cazul in care situatia este previzibila in aplicatia Java (de exemplu, sfarsitul unui fisier, depasirea dimensiunii unui tablou etc).

11/16/2013

31