vineri, noiembrie 18, 2005

Checked exceptions versus unchecked exceptions

Intrebare? De ce au ales cei de la SUN sa creeze o clasa de exceptii necheck-abile in compilare si anume clasa RuntimeExceptions? De ce nu au lasat obligatoriu ceck-area sau aruncarea lor asa cum e cazul celorlalte categorii de exceptii? Excludem din discutie clasele din Error care tin de viata interna a masinii virtuale. Dar exceptii?

Acest lucru ar parea in contradictie cu unele aspecte extrem de riguroase din Java. Sa luam de exemplu urmatorul aspect: Java este un limbaj puternic tipizat. Ideea este cat se poate de buna, pentru ca detectarea cat mai multor erori direct din faza de compilare aduce numai beneficii. In runtime nu mai porti grija unor eventuale exceptii prin faptul ca acestea sunt blocate direct din faza de compilare. Cum pot fi lasate exceptiile din RuntimeExceptions sa opreasca anormal programul chiar in timp ce el ruleaza?

Deci de ce RuntimeExceptions? Singurul raspuns plauzibil la care am ajuns este urmatorul care sa nu fie tratate? Avantajul propagarii lor spre metodele superioare fara a trata in cod acest lucru. Faptul ca ele nu sunt tratate prin check nu insemana ca ele nu se produc. Dovada ca e asa este faptul ca opresc executia programului. Ce e interesant in autopropagarea lor este faptul ca intreaga categorie de exceptii de tip RuntimeExceptions poate fi prinsa undeva mai sus, intr-o metoda apelanta. Si se poate presupune ca sunt multe si au o tratare asemanatoare: un ecran de eroare in care sa li se afiseze codul.

Sa consideram spre exemplu o arhitectura clasica J2EE. Avem spre exemplu un Action Struts care apeleaza un Manager din stratul de servicii care apelaza la randul lui un DOA. Apelul este de forma: Action->Manager->DAO. In DAO se vor produce o multime de exceptii sa zicem de tip SQLExceptions. Ele nu sunt erori de business ci eroari de sistem, produse sa spunem din caderea serverul de baze de date. Prin transformarea lor in erori de tip RuntimeExceptions, ele vor parcurge fara a fi tratate drumul pana la Action unde pot fi preluate de mecanismul generic pe care Struts il pune la dispozitie in acest sens. Ramane ca la nivelul de servicii sa fie aruncate exceptii de business care sa fie prinse si tratate de Action-uri prin modificarea corespunzatoare a fluxului de control al aplicatiei.

Deci daca la nivelul DOA exceptiile SQL sunt transformate in RuntimeExceptions, acestea vor urca singure prin stratul de servicii si Action-uri si vor fi prinse de sistemul generic de sus. Se mai poate face o distinctie de forma: business exceptions & system exceptions. Intr-un fel exceptiile de business tin de logica aplicatiei si ele sunt in general exceptii personalizate, declarate de programator. Ele fac parte din semnatura metodei publicate si au aceeasi importanta ca si parametrii metodei. Cel care va folosi acea metoda va sti ca trebuie sa trateze exceptia pe care aceasta o arunca. Exceptiile de sistem sunt in general de tip RuntimeExceptions care circula singure prin sistem si au o tratare generica.