Sunteți pe pagina 1din 18

Interfee

Interfeele, ca i clasele sau metodele abstracte, ofer un model de comportament care se presupune c va fi implementat de alte clase. Totui, interfeele ofer posibiliti mult mai mari dect clasele i metodele abstracte, att pentru Java, ct i pentru proiectarea obiectelor i a claselor, n general. Problema unicei moteniri Dup ce vei ctiga ceva mai mult experien n proiectare, va vei da seama c simplitatea ierarhiei de clase Java este oarecum restrictiv, mai ales atunci cnd dorii s folosii unele metode din clase aflate pe diferite ramuri" ale aceleiai ierarhii. S lum un exemplu care va clarifica aceast problem. S presupunem c avei o ierarhie de clase referitoare la biologie, pe primul nivel aflndu-se clasa Animal, iar mai jos, clasele Mamifer i Pasare. Printre atributele clasei Mamifer se numr naterea de pui vii i existena blnii. Clasa Pasare conine atribute cum ar fi depunerea de ou i existena ciocului. Dar cum vei defini o clas pentru ornitorinc, care, se tie, are blan, cioc i depune ou? Pentru crearea clasei Ornitorinc va trebui s combinai atributele din cele dou clase. Dar, deoarece clasele pot avea n Java o singur superclas, acest tip de problem nu poate fi rezolvat prea elegant. Alte limbaje OOP (orientate obiect) conin conceptul de motenire multipl, care rezolv aceast problem. Dac se folosete motenirea multipl, o clas poate avea mai multe superclase, mprumutnd atribute de la toate. Una dintre problemele motenirii multiple este aceea c limbajul de programare devine mai dificil de nvat, de folosit i de implementat. Problemele legate de apelarea metodelor i de modul de organizare a ierarhiei de clase devin mult mai complicate i este mult mai probabil s produc ambiguiti i confuzii. Deoarece unul din scopurile limbajului Java este simplitatea, s-a renunat la motenirea multipl n favoarea mai simplei moteniri unice. Pentru rezolvarea acestor probleme Java conine o alt ierarhie, total separat de ierarhia principal, care conine clase cu comportament combinat. Astfel, atunci cnd creai o nou clas, aceasta are o singur superclas primar, ns poate alege i alte comportamente din cealalt ierarhie. Aceast nou ierarhie se numete ierarhie de interfee. O interfa Java este o colecie de comportamente abstracte, care pot fi combinate n orice clas pentru a introduce n acea clas comportamente care nu pot fi motenite de la superclas. Tehnic, o interfa Java nu conine nimic altceva dect definiii de metode abstracte i constante - fr variabile de instan sau implementri de metode. Interfeele sunt implementate i folosite n biblioteca de clase Java ori de cte ori este nevoie ca un anumit comportament s fie implementat n alte clase. Ierarhia de clase Java, de exemplu, definete i folosete interfeele java.lang.Runnable, java.awt.image.ImageConsumer i java. awt. image.ImageProducer. Interfeele i clasele Clasele i interfeele, chiar dac au definiii diferite, au foarte multe n comun. Interfeele, ca i clasele, sunt declarate n fiiere surs, cte un fiier pentru fiecare interfa. Ca i clasele, acestea sunt compilate n fiiere .class folosind compilatorul Java. i, n majoritatea cazurilor, oriunde se poate folosi o clas (ca tip de dat pentru variabile, ca rezultat al unei conversii prin cast i aa mai departe) se poate folosi i o interfa. Programatorii Java folosesc termenul clas" pentru a se referi att la clase, ct i la interfee. Interfeele completeaz i extind puterea claselor i de aceea pot fi tratate aproape n acelai fel. Una dintre puinele diferene existente ntre clase i interfee este aceea c nu se poate obine o instan a unei interfee: operatorul new se folosete doar pentru crearea de instane ale unei clase. Implementarea i folosirea interfeelor

Cu interfeele putei face dou lucruri: s le folosii n clasele dumneavoastr sau s definii unele proprii. S ncepem cu primul caz. Pentru a folosi o interfa, trebuie folosit cuvntul cheie implements ca parte a definiiei clasei. Un astfel de exemplu este cel care a fost prezentat ntr-unul dintre capitolele anterioare: public { // . . . } n acest exemplu, java.applet.Applet este superclasa, ns interfaa Runnable extinde comportamentul implementat de aceasta. Deoarece interfeele nu ofer nimic altceva dect definiii abstracte de metode, va trebui s implementai aceste metode n clasele dumneavoastr folosind semnturile de metode provenite din interfa. Reinei c o dat inclus o interfa, va trebui s implementai toate metodele acesteia; nu putei s alegei doar metodele de care avei nevoie. Prin implementarea unei interfee, nseamn c declarai utilizatorilor clasei c vei suporta toate metodele acesteia. (Aceasta este o alt diferen ntre interfee i clasele abstracte; subclasele claselor abstracte pot alege care dintre metode s fie implementate sau suprascrise i s le ignore pe celelalte.) Dup ce clasa pe care ai scris-o implementeaz o interfa, subclasele acesteia vor moteni toate noile metode (care pot fi suprascrise sau suprancrcate) ca i cnd acestea ar fi fost definite n superclas. Cnd o clas motenete o superclas care implementeaz o anumit interfa, nu mai trebuie s folosii cuvntul cheie implements n definiia clasei respective. S lum un exemplu simplu - crearea unei noi clase, denumit Portocala. S presupunem c posedai deja o implementare bun a clasei Fruct i o interfa, ModelFruct, care reprezint ceea ce un Fruct este capabil s fac. Dorii ca portocala s fie un fruct, ns dorii s fie i un obiect sferic care s poate fi aruncat, rotit i aa mai departe. Iat cum se pot defini toate acestea: interface ModelFruct { void stricare ( ); void stoarcere ( ); // ... } class Fruct implements ModelFruct { private Color culoareaMea; private int zilePanaLaStricare; //... } class Neko extends java.applet.Applet implements Runnable

interface ModelSfera { void aruncare ( ); void rotire ( ); // ... } class Portocala extends Fruct implements ModelSfera { // aruncare ( ) poate sa provoace stoarcere ( ) // (caracteristici unice pentru clasa Portocala) }

Remarcai c n clasa Portocala nu este nevoie s se implementeze interfaa ModelFruct, deoarece, prin motenirea clasei Fruct, deja o implementeaz! Unul dintre avantajele acestei structuri este acela c v putei rzgndi n privina clasei de unde se deriv clasa Portocala (de exemplu, dac este implementat o clas mai bun, denumit Sfera) i totui clasa Portocala va nelege aceleai dou interfee: class Sfera implements ModelSfera { // derivata direct din clasa Object private float raza; // .. . } class Portocala extends Sfera implements ModelFruct { // ...utilizatorii clasei Portocala nu vor remarca aceasta // modificare! } Implementarea unor interfee multiple Spre deosebire de ierarhia de clase cu motenire unic n clasele dumneavoastr putei folosi oricte interfee dorii; clasa rezultat va implementa comportamentul combinat: al tuturor interfeelor incluse. Pentru a include mai multe interfee ntr-o clas, separai numele acestora prin virgule: public class Neko extends java. applet. Applet implements Runnable, Comestibil, Sortabil, Observable { // ... } Reinei totui c folosirea unor interfee multiple poate da natere la complicaii. Ce se ntmpl dac dou interfee definesc aceeai metod? Putei rezolva aceast problem n trei moduri: Dac metoda are aceeai semntur n ambele interfee, implementai n clasa dumneavoastr o metod a crei definiie satisface ambele interfee. Dac metodele au liste de parametri diferite, vei avea o situaie de suprancrcare a metodelor; implementai ambele metode, fiecare dintre definiii satisfcnd interfaa respectiv. Dac ambele metode au aceeai list de parametri, ns returneaz tipuri diferite, nu vei putea crea o metod care s le satisfac pe amndou (deoarece suprancrcarea metodelor ine cont doar de lista de parametri, nu de tipul de retur). n acest caz, ncercarea de compilare a unei clase care implementeaz ambele interfee va produce o eroare. Dac ajungei n aceast situaie, nseamn c interfeele dumneavoastr au erori de proiectare i trebuie reanalizate. Alte utilizri ale interfeelor Aproape oriunde putei folosi o clas, putei folosi i o interfa. De exemplu, s declarm o variabil de tip interfa: Runnable unObiectExecutabil = new ClasaMeaDeAnimatie( ) ; Atunci cnd se declar o variabil de tipul interfa, acest lucru presupune ca obiectul pe care l refer variabila s aib implementat acea interfa; deci se presupune c nelege toate metodele specificate

de interfa. n acest caz, deoarece variabila unObiectExecutabil conine un obiect de tip Runnable, se presupune c se poate apela metoda unObiectExecutabil.run( ). De asemenea, putei converti prin cast un obiect ntr-o interfa aa cum l convertii ntr-o alt clas. S ne ntoarcem la definiia clasei Portocala, care implementa att interfaa ModelFruct (prin superclasa sa, Fruct), ct i interfaa ModelSfera. Putei converti prin cast instane ale clasei Portocala att n clase, ct i n interfee: Portocala oPortocala = new Portocala ( ) ; Fruct unFruct = (Fruct)oPortocala; ModelFruct unModelFruct = (ModelFruct)oPortocala; ModelSfera unModelSfera = (ModelSfera)oPortocala; unFruct. stricare ( ); // fructele se strica unModelFruct .stoarcere ( ); // si se storc unModelFruct.aruncare ( ); // lucrurile care sunt ca fructele // nu se arunca unModelSfera.aruncare ( ); // dar lucrurile care sunt ca // sferele da oPortocala. stricare ( ); // portocalele pot face de toate oPortocala.stoarcere ( ); oPortocala.aruncare ( ) ; oPortocala.rotire ( ); Declaraiile i conversiile prin cast sunt folosite n acest exemplu pentru a limita comportamentul portocalei mai aproape de fruct sau de sfer. n final, reinei c interfeele, chiar dac se folosesc pentru combinarea metodelor diferitelor clase, pot fi folosite i pentru combinarea unor constante utile. De exemplu, dac o interfa definete un set de constante care sunt folosite apoi n mai multe clase, valoarea acestor constante poate fi modificat global fr a trebui s modificai toate clasele. Acesta este un alt caz n care folosirea interfeelor pentru separarea proceselor de proiectare i de implementare conduce la obinerea unui cod mai generic i mai uor de ntreinut.

Crearea i extinderea interfeelor


Dup o perioad de folosire a interfeelor putei trece la definirea unor interfee proprii. Acestea arat destul de asemntor claselor; ele sunt declarate cam n acelai fel i pot fi aranjate ntr-o ierarhie. Totui, pentru declararea unei interfee trebuie s respectate anumite reguli. Interfee noi Declararea unei interfee noi se face n felul urmtor: public interface Crescator { // .... } Acest enun este practic identic cu definiia unei clase, cu singura diferen c este folosit cuvntul cheie interface n locul cuvntului class. n definiia interfeei putei avea metode i constante. Metodele din cadrul unei interfee sunt public i abstract; putei s le declarai explicit n acest fel sau, dac nu, oricum vor fi transformate n metode public i abstract. Nu putei declara o metod private sau protected n cadrul unei interfee. De exemplu, n urmtoarea definiie a interfeei Crescator, metoda crescut ( ) este declarat explicit public i abstract. n timp ce metoda maicrescut ( ) este declarat implicit: public interface Crescator { public abstract void crescut ( ); // declarata explicit public // si abstract void maiCrescut ( ); // declarata implicit public si // abstract }

Observai c, la fel ca i n cazul metodelor abstracte din clase, metodele din interfee nu au coninut. Reinei: o interfa necesit doar proiectare, nu presupune i implementare. In afar de metode, interfeele pot conine i variabile, ns acestea trebuie declarate public, static i final (deci constante). Ca i n cazul metodelor, acest lucru nu trebuie fcut explicit; variabilele sunt considerate implicit public, static i final chiar i fr a folosi aceti modificatori. Iat definiia interfeei Crescator, care conine dou noi variabile: public interface Crescator { public static final int incrementare = 10; long nrmax = 1000000; // devine public, static si final public abstract void crescut ( ); // declarata explicit public // si abstract void maiCrescut ( ); // declarata implicit public si abstract } Interfeele trebuie s posede, ca i clasele, o protecie de pachet sau public. O interfa nepublic are metode i constante de acelai tip, acestea neputnd fi folosite dect n clasele sau interfeele din acelai pachet. Interfeele, ca i clasele, pot aparine unui pachet dac folosii instruciunea package n prima linie din fiierul surs. La fel ca i clasele, interfeele pot importa interfee sau clase din alte pachete. Metodele din cadrul interfeelor Iat o problem privind metodele din cadrul interfeelor: ele trebuie s fie abstracte i s se aplice oricrui tip de clas, dar cum se poate defini lista de parametri pentru aceste metode? Nu tii dinainte ce clas urmeaz s le foloseasc! Rspunsul const n faptul c, aa cum ai nvat mai devreme, putei folosi un nume de interfa peste tot unde poate fi folosit un nume de clas. Prin definirea parametrilor metodei de tip interfa putei crea parametri generici care funcioneaz pentru orice clas care ar folosi aceast interfa. S lum, de exemplu, interfaa ModelFruct, care definete metodele (fr parametri) stricare ( ) i stoarcere ( ). Mai putei avea o metod, germinareSeminte ( ), care are un singur argument: fructul nsui. De ce tip urmeaz s fie acest argument? Nu poate fi de tip Fruct, deoarece putei avea o clas derivat din ModelFruct (deci care implementeaz interfaa ModelFruct) i care s nu fie, de fapt, un fruct. Soluia este de a declara n interfa argumentul de tip ModelFruct: public interface ModelFruct { public germinareSeminte (ModelFruct fr) { // } } Apoi, n implementarea acestei metode ntr-o clas, putei converti prin cast argumentul genericModelFruct n obiectul corespunztor: public class Portocala extends Fruct { public germinareSeminte(ModelFruct fr) { Portocala oPortocala = (Portocala)fr; // . . . } } Derivarea interfeelor Ca i n cazul claselor, interfeele pot fi organizate ntr-o ierarhie. Atunci cnd o interfa motenete o alt interfa, subinterfaa" primete toate metodele i constantele definite n superinterfa". Pentru a deriva (extinde) o interfa vei folosi cuvntul cheie extends, la fel ca n cazul definiiilor claselor: public interface ModelFruct extends ModelMancare {

// ... } Totui, spre deosebire de clase, ierarhia de interfee nu posed echivalentul unei clase Object; aceast ierarhie nu are un vrf". Interfeele pot exista independent sau pot moteni o alt interfa. De asemenea, spre deosebire de ierarhia de clase, ierarhia de interfee este una cu motenire multipl. De exemplu, o singur interfa poate moteni oricte clase are nevoie (separate prin virgul, n acea parte a definiiei care folosete cuvntul cheie extends); noua interfa va conine o combinaie de metode i constante motenite de la prini". Iat definiia unei interfee care motenete mai multe interfee: public interface InterfataAglomerata extends Runnable, Crescator, ModelFruct, Observable { // ... } n interfeele cu motenire multipl, regulile de gestionare a conflictelor ntre numele metodelor sunt aceleai ca pentru clasele care folosesc mai multe interfee; metodele care difer numai prin tipul de retur vor genera o eroare de compilare.

Clase interioare
Clasele cu care ai lucrat pn acum sunt toate membre ale unui pachet, fie c ai folosit instruciunea package, urmat de numele unui pachet, fie c a fost folosit pachetul prestabilit. Clasele care aparin unui pachet sunt cunoscute drept clase de nivel nalt (top-level classes). La introducerea Java, acestea erau singurele clase suportate de limbaj. ncepnd cu Java 1.1, putei defini o clasa n interiorul altei clase, ca i cnd ar fi o metod sau o variabil. Astfel de clase se numesc clase interioare (inner classes). Listingul urmtor prezint appletul Interior, care folosete o clas interioar, denumit ButonAlbastru pentru a reprezenta butoanele care au culoarea de fundal albastr. Textul complet al programului Interior.java. 1: import java.awt.Button; 2: import java.awt.Color; 3: 4: public class Interior extends java.applet.Applet { 5: Button b1 = new Button ("0ne"); 6: ButonAlbastru b2 = new ButonAlbastru("Two"); 7: 8: public void init ( ) { 9: add(b1); 10: add(b2); 11: } 12: class ButonAlbastru extends Button { 13: ButonAlbastru (String eticheta) { 14: super(eticheta) { 15: this .setBackground(Color.blue) ; 16: } 17: } 18: } n acest exemplu, clasa ButonAlbastru nu este dect o clas ajuttoare inclus n acelai fiier surs ca i clasa principal a programului. Singura diferen este c aceast clas ajuttoare este definit n cadrul fiierului clas, ceea ce aduce cteva avantaje:

Clasele interioare sunt invizibile pentru alte clase, ceea ce nseamn c nu trebuie s v facei probleme privind conflictele de nume cu alte clase. Clasele interioare pot avea acces la variabilele i metodele din domeniul de vizibilitate al clasei de nivel superior, lucru care nu ar fi fost valabil dac ar fi fost separate. n majoritatea cazurilor, o clas interioar este o clas de dimensiuni reduse i cu un scop limitat. n applet-ul Interior, deoarece clasa ButonAlbastru nu conine atribute sau metode complexe, este indicat pentru a fi implementat drept clas interioar. Numele clasei interioare este asociat cu numele clasei care o conine i este atribuit automat la compilarea programului. n exemplul clasei ButonAlbastru, JDK i va atribui numele Interior$ButonAlbastru.class. Clasele interioare, chiar dac par c aduc mbuntiri minore limbajului Java, reprezint, de fapt, o modificare semnificativ a limbajului. Regulile care guverneaz domeniul de vizibilitate al unei clase interioare sunt aceleai care se aplic i variabilelor. Numele unei clase interioare nu este vizibil n afara domeniului su, exceptnd cazul cnd se folosete numele complet, lucru care ajut la structurarea claselor n cadrul pachetului. Codul unei clase interioare poate folosi nume simple, din domeniile de vizibilitate pe care le cuprinde, cum ar fi variabilele de clas i de instan ale claselor pe care le conine, precum i variabilele locale din blocurile incluse. n plus, putei defini o clas de nivel nalt ca membru static al unei alte clase de nivel nalt. Spre deosebire de o clas interioar, o clas de nivel nalt nu poate folosi direct variabilele de instan ale unei alte clase. Posibilitatea de a imbrica n acest fel clasele permite oricrei clase de nivel nalt s ofere o organizare de tipul pachetelor pentru un grup de clase de nivel mai sczut, nrudite din punct de vedere logic.

Exceptii Java
Pn n acest moment, este mai mult ca sigur c ai ntlnit cel puin o situaie de excepie Java - probabil atunci cnd ai introdus greit numele unei metode sau ai fcut o greeal n cod care a dus la apariia unei probleme. Se poate, de asemenea, ca programul s se termine anormal, dup ce a afiat pe ecran ceva erori. Aceste erori sunt excepii. Atunci cnd programul se termin brusc, este din cauz c a fost semnalat o excepie (thrown - aruncat"). Excepiile fi semnalate de sistem sau, explicit, de programul pe care l-ai scris. Am folosit termenul "semnalate" deoarece excepiile pot fi i interceptate (caught). Interceptarea unei excepii presupune tratarea situaiilor speciale pentru ca programul dumneavoastr s nu se mai blocheze. Faptul c o excepie a fost semnalat nseamn, n Java, c "a aprut o eroare". Excepiile Java sunt, de fapt, obiecte, instane ale unor clase care motenesc clasa Throwable. O instan a clasei Throwable este creat atunci cnd se semnaleaz o excepie. Figura urmtoare prezint o poriune ierarhiei de clase pentru excepii.
Throwable

Error

Exception

IOException RuntimeException ClassNotFoundE xception AWTException FileNotFound Exception EOFException MalFormedURL Exception SocketException

Clasa Throwable are dou subclase: Error i Exception. Instanele clasei Error reprezint erori interne ale mediului de lucru Java (maina virtual). Aceste erori sunt rare i, de obicei, fatale; nu putei face mare lucru cu ele (nici s le interceptai i nici s le semnalai), exist pentru ca Java s le poat folosi dac are nevoie de ele. Subclasele Exception se mpart n dou grupuri:

Excepii de execuie (runtime), care sunt subclase ale clasei RuntimeException, cum ar fi ArrayIndexOutofBounds, SecurityException sau NullPointerException Alte excepii, cum ar fi EOFException sau MalformedURLException Majoritatea claselor de excepie fac parte din pachetul java.lang (cum ar fi Throwable, Exception sau RuntimeException). Celelalte pachete definesc i ele excepii, care pot fi folosite n toat biblioteca de clase. De exemplu, pachetul java.io definete o clas de excepie generic, denumit IOException, care nu este folosit doar n pachetul java.io, pentru excepiile de intrare/ieire (EOFException, FileNotFoundException), ci i n clasele pachetului java.net, pentru excepii de reea cum ar fi MalformedURLException.

Gestionarea excepiilor
n majoritatea cazurilor, compilatorul Java impune gestionarea excepiilor atunci cnd ncercai s folosii metode ce presupun apariia unor excepii; dac nu tratai aceste excepii, codul nu va fi compilat. n aceast seciune vei nva despre verificarea consistenei i despre folosirea cuvintelor cheie try, catch i finally pentru tratarea excepiilor ce pot aprea.

Verificarea consistenei excepiilor


Cu ct lucrai mai mult cu biblioteci Java, cu att mai mult crete posibilitatea de a ntlni o eroare (o excepie!) de compilare, asemntoare acesteia: Program.java:32: Exception java.lang.InterruptedException must be caught or it must be declared in the throws clause of this method. (Program.java:32: Excepia java.lang.InterruptedException trebuie interceptat sau trebuie declarat n clauza throws a acestei metode.) n Java, o metod poate indica tipurile de erori pe care le poate semnala. De exemplu, metodele care citesc din fiiere pot semnala excepii IOException, deci aceste metode sunt declarate cu un modificator special care indic potenialele erori. Atunci cnd folosii aceste metode n programele dumneavoastr Java, trebuie s v protejai codul mpotriva acestor excepii. Aceast regul este verificat chiar de compilator, n acelai fel n care verific i dac ai apelat metodele cu numrul corespunztor de argumente sau dac ai atribuit variabilelor tipurile de date declarate. De ce se face aceast verificare? Deoarece astfel programele dumneavoastr sunt mai puin expuse erorilor fatale i terminrii anormale, pentru c tii dinainte ce tipuri de excepii pot fi semnalate de metodele folosite n program. Nu trebuie s mai citii cu atenie documentaia sau codul unui obiect pentru a v asigura c ai tratat toate potenialele probleme - Java face aceste verificri n locul dumneavoastr. Pe de alt parte, dac definii metodele astfel nct s indice excepiile pe care le pot semnala, Java poate avertiza utilizatorii acestor obiecte c trebuie s trateze erorile respective.

Protejarea codului i interceptarea erorilor


S presupunem c ai scris un cod i c la un test de compilare ai obinut un mesaj de excepie. n funcie de mesaj, fie interceptai eroarea, fie declarai c metoda o poate semnala. S lum primul caz: interceptarea potenialelor excepii. Pentru a intercepta o excepie trebuie realizate dou lucruri: Protejai codul care conine metoda ce poate semnala excepia n cadrul unui bloc try. Testai i tratai excepia n cadrul unui bloc catch.

Operaiunile try (ncearc) i catch (intercepteaz) nseamn, de fapt, ncearc aceast poriune de cod, care poate cauza o excepie. Dac se execut cu succes, continu programul. dac nu, intercepteaz excepia i trateaz-o." Un astfel de caz este atunci cnd creai animaie pe care o oprii o dat pe secund: try { Thread.sleep(1000); } catch (InterruptedException e) { } Chiar dac aici s-au folosit instruciunile try i catch, acesta nu este un exemplu prea bun. Iat ce se ntmpl n aceste instruciuni: metoda de clas Thread.sleep() poate s semnaleze o excepie de tip InterruptedException, ceea ce nseamn c firul de execuie a fost oprit dintr-un motiv oarecare. Pentru a trata aceast excepie, apelul metodei sleep() este ncadrat ntr-un bloc try, dup care se definete un bloc catch asociat. Acest bloc catch primete toate obiectele InterruptedException care sunt semnalate din blocul try. Motivul pentru care acest cod nu constituie un bun exemplu de tratare a excepiilor este c nu exist nimic n interiorul blocului catch - cu alte cuvinte, se intercepteaz excepia atunci cnd apare, ns ca rspuns la aceasta nu se face nimic. Cu excepia cazurilor simple (cum e acesta, unde excepia ntr-adevr nu conteaz), trebuie s scriei n cadrul blocului catch un cod care s realizeze o anumit aciune dup apariia excepiei. Partea din interiorul instruciunii catch este similar listei de argumente a unei metode. Ea conine clasa a crei excepie a fost interceptat i un nume de variabil (de obicei se folosete e). Astfel, n cadrul blocului putei s v referii la obiectul excepie interceptat. O folosire uzual a acestui obiect este apelarea metodei getMessage(). Aceast metod este prezent n toate excepiile i afieaz un mesaj detaliat referitor la ceea ce s-a ntmplat. Urmtorul exemplu reprezint o versiune revizuit a instruciunii try.. . catch,din exemplul anterior: try { Thread.sleep(1000) ; } catch (InterruptedException e) { System.out.println("Eroare: " + e.getMessage()); }

Clauza finally
S presupunem c n codul dumneavoastr exist o anumit aciune care trebuie neaprat executat, indiferent ce se ntmpl, indiferent dac excepia este semnalat sau nu. Acest lucru se face, de obicei, pentru a elibera anumite resurse dup folosire, pentru a nchide un fiier dup deschidere sau ceva de acest gen. Chiar dac putei introduce aceste aciuni att n cadrul unui bloc catch, ct i n afara sa, aceasta nseamn o duplicare a codului n dou locuri diferite. n loc s procedai astfel, introducei o copie a codului ntr-o poriune special a blocului try. . .catch, denumit finally. Urmtorul exemplu prezint modul cum este structurat un bloc try. . .catch . . . finally: try { citesteFisierText(); } catch (IOException e) { // tratati erorile de intrare/iesire } finally { inchideFisierText() ; }

Instruciunea finally este folositoare, de fapt, n afara excepiilor; putei, de asemenea, s o folosii pentru executarea unui cod de reiniializare dup o instruciune return, break sau continue din cadrul unui ciclu. n ultimul caz putei folosi o instruciune try doar cu blocul finally, fr blocul catch.

Declararea metodelor care pot semnala exceptii


n exemplele anterioare ai nvat cum se trateaz metodele care pot semnala excepii (prin protejarea codului i interceptarea eventualelor excepii). Compilatorul Java verific dac v-ai ocupat ntr-un fel sau altul de excepiile care pot aprea - dar cum tie el asupra cror excepii s v atrag atenia? Rspunsul este c metoda original indic n semntura sa excepiile pe care le poate semnala. Putei folosi acest mecanism n propriile metode, de fapt, este bine s procedai astfel pentru a v asigura c utilizatorii vor fi avertizai asupra excepiilor ce pot aprea. Pentru a indica faptul c o metod poate semnala o excepie, vei folosi n definiia sa o clauz special, denumit throws.

Clauza throws
Pentru a indica faptul c o poriune a unei metode poate semnala o excepie, este suficient s adugai cuvntul cheie throws dup semntura metodei (nainte de acolada deschis) i s specificai numele excepiilor pe care le poate semnala metoda dumneavoastr: public boolean metodaMea(int x, int y) throws oExceptie { // ... } Dac metoda dumneavoastr poate semnala mai multe tipuri de excepii, putei s le specificai pe toate n clauza throws, separate prin virgule: public boolean oAltaMetodaAMea(int x, int y) throws oExceptie, oADouaExceptie, oATreiaExceptie { // ... } La fel ca n cazul catch, putei folosi o superclas a unui grup de excepii pentru a indica faptul c metoda dumneavoastr poate semnala oricare dintre subclasele acelei excepii: public void oAltaMetoda() throws IOException { // .. . } Specificarea clauzei throws n definiia metodei dumneavoastr nu nseamn dect c metoda poate semnala o excepie dac ceva merge prost, nu i c va face acest lucru. Clauza throws ofer doar o informaie suplimentar referitoare la potenialele excepii i permite compilatorului Java s se asigure c metoda este corect folosit de utilizatori.

Manipularea datelor prin fluxuri Java


Majoritatea programelor pe care le creai n Java trebuie s interacioneze cu anumite surse de date. Exist nenumrate metode de pstrare a informaiilor pe un calculator, cum ar fi fiiere pe hard disc sau pe CD-ROM, pagini ntr-un site Web sau chiar n memoria calculatorului. Ai putea crede c exist diferite tehnici pentru manipularea datelor de pe diversele dispozitive de stocare. Din fericire, nu este cazul. n Java, informaiile pot fi stocate sau apelate folosind un sistem de comunicaie denumit flux (stream), implementat n pachetul java.io. Fluxurile reprezint un mecanism puternic de manipulare a datelor.

Introducere n fluxuri
Toate datele din Java sunt scrise sau citite folosind fluxuri. Fluxurile, aa cum le arat i denumirea, transport ceva dintr-un loc n altul. Un flux (stream) reprezint calea pe care o urmeaz datele ntr-un program. Un flux de intrare transport datele de la surs la program, iar un flux de ieire transport datele din program ctre o destinaie. Exist dou tipuri de fluxuri: fluxuri de octei i fluxuri de caractere. Octeii pot pstra valori ntregi din domeniul 0. . . 255. n acest format pot fi reprezentate o multitudine de date, cum ar fi date numerice, programe executabile, comunicaii Internet sau cod Java (bytecode) - adic fiierele clas care sunt executate pe o main virtual Java. De fapt, orice tip de date poate fi reprezentat printr-o serie de octei. Fluxurile de caractere reprezint un tip special de fluxuri de octei, care se folosesc numai pentru datele de tip text (tipribile). Ele difer de fluxurile de octei prin faptul c setul de caractere Java suport codificarea Unicode, un standard prin care se pot reprezenta mai multe caractere dect dac s-ar folosi octei. Toate datele de tip text, cum ar fi fiierele text, paginile Web sau alte formate de text, trebuie s foloseasc fluxuri de caractere.

Folosirea unui flux


Indiferent dac folosii fluxuri de octei sau de caractere, procedura este asemntoare. n cazul irurilor de intrare, prima etap const n crearea unui obiect asociat cu sursa de date. De exemplu, dac sursa este un fiier de pe hard discul dumneavoastr, acestuia trebuie s i se asocieze un obiect de tip FileInputStream. Odat obinut obiectul asociat fluxului, putei citi informaii din acest flux folosind una dintre metodele obiectului. Clasa FileInputStream posed o metod read(), care returneaz un octet citit din fiier. Atunci cnd ai terminat de citit informaia din flux, trebuie s apelai metoda close(), pentru a indica faptul c ai terminat de folosit fluxul. n cazul fluxurilor de ieire, vei ncepe prin a crea un obiect asociat cu destinaia datelor. Un astfel de obiect poate fi creat pornind de la clasa BufferedReader, care constituie o metod eficient de creare a fiierelor text. Metoda write() reprezint cea mai simpl metod de a transmite informaii ctre destinaia unui flux. De exemplu, metoda write() aparinnd dasei BufferedReader poate transmite caractere individuale unui flux de ieire. Ca i n cazul fluxurilor de intrare, pentru un flux de ieire trebuie apelat metoda close () atunci cnd nu mai exist date de transmis.

Filtrarea unui flux Cea mai simpl metod de a folosi un flux este de a l crea i de a-i apela metodele de transmitere sau de recepie a datelor, n funcie de rolul lui (flux de intrare sau flux de ieire). Majoritatea claselor folosite n prezent permit obinerea unor rezultate mai sofisticate prin asocierea fluxului cu un filtru, nainte de a citi sau scrie date. Un filtru este un tip de flux care schimb modul n care se lucreaz cu un flux existent. Procedura de folosire a unui filtru pentru un flux presupune urmtoarele: Crearea unui flux asociat cu sursa de date sau cu destinaia datelor. Asocierea unui filtru cu acest flux. Citirea i scrierea datelor de la/n filtru, i nu direct n flux. Metodele pe care le apelai n cazul filtrelor sunt aceleai cu cele pe care le apelai n cadrul fluxurilor: exist metodele read () i write (), asemntoare celor ale unui flux nefiltrat. Putei chiar s asociai un filtru unui alt filtru, crend situaii de genul: un flux de intrare este asociat unui fiier text, este trecut printr-un filtru de traducere romno-englez i, n final, este trimis la destinaie - o persoan care dorete s l citeasc.

Fluxuri de octei
Toate fluxurile de octei sunt subclase ale InputStream sau OutputStream. Aceste clase sunt abstracte, deci nu putei obine un flux prin crearea de obiecte direct din aceste clase. n schimb, putei crea fluxuri prin folosirea unor subclase ale acestora, cum ar fi: FileInputStream i FileOutputStream-Octei stocai n fiiere pe disc, pe CD-ROM sau pe alte dispozitive de stocare. DataInputStream i DataOutputStream - Un flux de octei filtrat, din care pot fi citite date de tip ntreg sau n virgul mobil (float). InputStream este superclasa tuturor fluxurilor de intrare.

Fluxuri de fiiere
Fluxurile de octei cu care vei lucra de obicei sunt fluxuri de fiiere folosite pentru transferul de date ntre program i fiierele aflate pe hard discuri, pe CD-ROM sau pe alte dispozitive de stocare ce pot fi referite printr-o cale de director i un nume. Putei transmite octei unui flux de ieire i putei citi octei dintr-un flux de intrare. Fluxuri de intrare din fiiere Un flux de intrare din fiier poate fi creat cu ajutorul constructorului FileInputStream (String). irul transmis ca argument trebuie s fie numele fiierului. Putei include i calea ctre fiier, n cazurile n care acesta se afl n alt director dect cel care conine clasa. Urmtoarea instruciune creeaz un flux de intrare pentru fiierul date.dat: FileInputStream fis = new FileInputStream("date.dat") ; Dup crearea fluxului de intrare din fiier, putei citi octei din acesta apelndu-i metoda read (). Aceast metod returneaz o valoare ntreag ce conine urmtorul octet din flux. Dac metoda retumeaz -1, care nu este o valoare acceptat pentru un octet, nseamn c s-a ajuns la sfritul fluxului de fiier. Pentru a citi mai muli octei din flux se folosete metoda read(byte[], int, int), care posed urmtoarele argumente: Un tablou de octei n care se vor memora datele Elementul din cadrul tabloului unde se va stoca primul octet de date Numrul de octei care se vor citi Spre deosebire de alte metode read (), aceasta nu retumeaz date din flux, ci un ntreg care reprezint numrul de octei citii sau -1 dac nu s-au citit octei i s-a ajuns la sfritul fluxului.

Urmtoarele instruciuni folosesc un ciclu while pentru a citi datele din obiectul df de tip FileInputStream: int octetNou = 0; while (octetNou != -1) { octetNou = df.read(); System.out.println(octetNou +" ); } Aceast bucl citete ntregul fiier referit de obiectul df, cte un octet o dat, i afieaz valoarea fiecrui octet, urmat de un spaiu. De asemenea, cnd se ajunge la sfritul fiierului va fi afiat valoarea -1, lucru pe care l putei evita folosind un test if. Fluxuri de ieire n fiiere Un flux de ieire n fiier poate fi creat folosind constructorul FileOutputStream (String). Utilizarea sa este identic cu cea a constructorului FileInputStream (String), deci putei specifica i calea pn la fiier, nu numai numele acestuia. Trebuie s avei grij atunci cnd specificai fiierul n care scriei. Dac folosii numele unui fiier deja existent, o dat cu nceperea scrierii datelor, acesta va fi ters definitiv. Putei crea un flux de ieire n fiier care s adauge date (append) la sfritul unui fiier existent folosind constructorul FileOutputStream(String, boolean). irul specific numele fiierului, iar argumentul boolean, dac are valoarea true, va aduga datele la sfritul fiierului, n loc s suprascrie datele existente. Pentru a scrie octei ntr-un fiier se folosete metoda write ( int) a fluxului de ieire. Dup ce s-a scris ultimul octet, fluxul trebuie nchis folosind metoda close (). Pentru a scrie mai muli octei se poate folosi metoda write(byte[], int, int), care funcioneaz similar metodei read (byte[], int, int) descris anterior. Argumentele acestei metode sunt tabloul care conine octeii ce vor fi scrii, poziia de nceput din tablou i numrul de octei ce trebuie scrii.

Filtrarea fluxurilor
Fluxurile filtrate sunt fluxuri care modific informaia trimis printr-un flux existent. Acestea sunt create folosind subclase ale FilterInputStream sau FilterOutputStream. Aceste filtre nu realizeaz singure nici un fel de operaie de filtrare. De fapt, ele posed subclase, cum ar fi BufferInputStream sau DataOutputStream, care sunt folosite pentru anumite tipuri de filtrri.

Filtre de octeti
Informaia este furnizat mai rapid dac poate fi transmis n blocuri de date mai mari, chiar dac aceste blocuri sunt recepionate mai repede dect pot fi procesate. Un tampon (buffer) reprezint o zon n care se pot pstra date nainte de a fi nevoie s fie citite sau scrise de un program. Prin folosirea unui tampon putei avea acces la date fr s accesai din nou sursa original de date. Fluxuri cu tampon Un flux de intrare cu tampon umple un tampon cu date care nu au fost nc procesate; cnd programul are nevoie de aceste date, le caut n zona tampon nainte de a apela fluxul surs original. Aceast tehnic este mai eficient. Aceast descongestionare a fluxului nu face altceva dect s uureze eforturile de folosire a acestuia. Fluxurile de octei folosesc clasele BufferedInputStream i BufferedOutputStream. Fluxurile de intrare cu tampon sunt create folosind unul din constructorii:

BufferedInputStream(InputStream) Creeaz un flux de intrare cu tampon pentru obiectul InputStream specificat. BufferedInputStream(InputStream, int) Creeaz fluxul de intrare cu tampon InputStream specificat, avnd o dimensiune a zonei tampon egal cu valoarea argumentului ntreg. Cea mai uoar modalitate de a citi date dintr-un flux de intrare cu tampon este de a apela metoda read () a acestuia, fr argumente; aceasta retumeaz o valoare ntreag ntre 0 i 255, care reprezint urmtorul octet din flux. Dac s-a ajuns la sfritul fluxului i nu s-a gsit nici un octet, se retumeaz valoarea -1. Putei, de asemenea, folosi metoda read(byte [] , int, int), care este disponibil i pentru alte fluxuri de intrare, caz n care datele sunt ncrcate ntr-un tablou de octei. Un flux de ieire cu tampon este creat prin folosirea urmtorilor constructori: BufferedOutputStream(OutputStream) Creeaz un flux de ieire cu tampon pentru obiectul OutputStream specificat. BufferedOutputStream(OutputStream, int) Creeaz fluxul de ieire cu tampon OutputStream specificat, alocnd o zon tampon de dimensiunea specificat prin argumentul int. Pentru a scrie un singur octet n fluxul de ieire poate fi folosit metoda write(int) a acestuia, iar pentru a scrie mai muli octei dintr-o dat se poate folosi metoda write (byte [ ], int, int). Argumentele acestei metode sunt tabloul de octei, poziia iniial a acestuia i numrul de octei care trebuie transmis. Atunci cnd datele sunt direcionate ntr-un flux cu tampon, coninutul acestuia nu va fi transmis ctre destinaie dect dup ce zona tampon s-a umplut sau dac se apeleaz explicit metoda flush() a fluxului. Fluxuri de date Dac trebuie s lucrai cu date care nu sunt reprezentate drept octei sau caractere, putei folosi fluxuri de date de intrare i de ieire. Aceste fluxuri filtreaz un flux de octei existent astfel nct urmtoarele tipuri de date s poat fi citite direct din flux: boolean, byte, double, float, int, long i short. Un flux de date de intrare este creat folosind constructorul DataInputStream (InputStream). Argumentul trebuie s fie un flux de intrare existent, de exemplu, un flux de intrare cu tampon sau un flux de intrare din fiier. Reciproc, un flux de date de ieire necesit utilizarea constructorului DataOutputStream (OutputStream), care folosete ca argument fluxul de ieire asociat. Urmtoarea list prezint metodele de citire i de scriere ce pot fi folosite pentru fluxurile de date de intrare, respectiv de ieire: readBoolean(), writeBoolean(boolean) readByte(), writeByte (int) readDouble(), writeDouble(double) : readFloat(), writeFloat(float) readInt(), writeInt(int) readLong(), writeLong(long) readShort(), writeShort(int) Fiecare dintre metodele de intrare returneaz tipul de dat primitiv indicat de numele metodei. De exemplu, metoda readFloat () retumeaz o valoare float. Exist i metodele readUnsignedByte () i readUnsignedShort (), care pot citi valori de tip octet sau ntregi scuri fr semn. Aceste tipuri de date nu sunt suportate n Java, deci vor fi retumate ca valori ntregi. Octeii fr semn iau valori de la 0 la 255. Aceasta difer de tipul de variabil byte din Java, care ia valori ntre -128 i 127. n acelai fel, o variabil ntreag scurt fr semn ia valori ntre 0 i 65535, n loc de domeniul -32768 i 32767, suportat de tipul short n Java. Nu toate metodele de citire dintr-un flux de date de intrare retumeaz o valoare ce poate indica faptul c s-a ajuns la sfritul fluxului. V mai putei atepta la apariia excepiei EOFException care este

semnalat la atingerea sfritului unui flux. Ciclul n care se citesc date poate fi ncadrat ntr-un bloc try, iar instruciunea catch asociat trebuie s trateze doar excepiile EOFException. In cadrul blocului catch putei s apelai i metoda close () i s efectuai alte aciuni de reiniializare.

Fluxuri de caractere
Aceste fluxuri se folosesc pentru lucrul cu orice text reprezentat n format ASCII sau Unicode . Clasele folosite pentru a citi i scrie aceste fluxuri sunt subclase ale daselor Reader i Writer. Este indicat s folosii aceste clase pentru lucrul cu text, i nu fluxuri de octei. Tehnicile pentru lucrul cu fluxuri de caractere s-au mbuntit considerabil n versiunile ulterioare Java 1.02, o dat cu introducerea claselor Reader i Writer i a subclaselor acestora; ele ofer suport pentru setul de caractere Unicode i permit o manevrare mai uoar a textelor. Un applet java compatibil cu versiunea 1.02 poate citi caracterele folosind clasele pentru fluxuri de octei descrise anterior. Citirea fiierelor text Principala clas folosit pentru citirea de fluxuri de caractere dintr-un fiier este FileReader. Aceast clas motenete clasa InputStreamReader, care citete un flux de octei i i convertete n valorile ntregi corespunztoare caracterelor Unicode. Un flux de intrare de caractere este asociat unui fiier folosind constructorul FileReader (String). irul reprezint numele fiierului i poate conine i calea pn la acesta. Urmtoarea instruciune creeaz un obiect FileReader denumit web i l asociaz cu fiierul text denumit index. html: FileReader web = new FileReader("index.html); Dup ce ai obinut un obiect de acest tip, putei s apelai urmtoarele metode de citire a caracterelor din fiier: read () returneaz urmtorul caracter din flux, ca valoare ntreag read (char [ ], int, int) citete caractere ntr-un tablou i primete ca argumente tabloul de caractere, poziia de ncepere i numrul de caractere de citit. A doua metod funcioneaz asemntor echivalentului su din clasele de fluxuri de intrare de octei. n loc s returneze caracterul urmtor din flux, aceasta returneaz fie numrul de caractere citite, fie -1 dac s-a ajuns la sfritul fluxului i nu s-a citit nimic. Urmtoarea metod ncarc un fiier text folosind obiectul FileReader i afieaz caracterele coninute de acesta: FileReader text = new FileReader("readme.txt"); int octetCitit; do { octetCitit = text.read(); if (octetCitit != -1) System.out.print( (char)octetCitit) ; } while (octetCitit != -1) ; System.out.println(" "); text.close() ; Deoarece metoda read () a unui flux de caractere returneaz o valoare ntreag, trebuie s convertii prin cast aceast valoare nainte de a o afia, de a o salva ntr-un tablou sau de a o folosi ntr-un ir. Fiecare caracter posed un cod numeric care reprezint poziia sa n setul de caractere Unicode. Valoarea ntreag citit din flux reprezint chiar acest cod numeric. Dac dorii s citii din fiier o ntreag linie de text, i nu caracter cu caracter, putei folosi o combinaie a daselor FileReader i BufferedReader.

Clasa BufferedReader citete un caracter din fluxul de intrare i l memoreaz ntr-o zon tampon, pentru mai mult eficien. Pentru a crea o versiune care folosete tampon, trebuie s existe un obiect de tip Reader. Pentru crearea obiectului BufferedReader se pot folosi urmtorii constructori: BufferedReader(Reader) Creeaz un flux de caractere cu zon tampon, asociat obiectului Reader specificat (de exemplu FileReader). BufferedReader (Reader, int) Creeaz un flux de caractere asodat obiectului Reader, cu o zon tampon de dimensiunea specificat de argumentul ntreg. Dintr-un flux de caractere cu tampon se poate citi folosind metodele read () i read(char[ ] , int, int), asemntoare celor descrise pentru FileReader. Putei citi o ntreag linie de text folosind metoda readLine (). Metoda readLine () returneaz un obiect String care conine urmtoarea linie de text din flux, fr a include i caracterul (sau caracterele) care reprezint sfritul de linie. Dac se ajunge la sfritul fluxului, valoarea irului returnat va fi null. Sfritul de linie este indicat astfel: Un caracter de linie nou (newline - '\n') Un caracter de retur de car (carriage return \r) Un retur de car urmat de o linie nou Scrierea n fiiere text Clasa FileWriter este folosit pentru scrierea unui flux de caractere ntr-un fiier. Aceasta este o subclas a OutputStreamWriter, care are rolul de a converti codurile caracterelor Unicode n octei. Exist doi constructori FileWriter: FileWriter (String) i FileWriter (String, boolean). irul din primul argument reprezint numele fiierului ctre care va fi direcionat fluxul de caractere i poate conine i calea. Argumentul opional de tip boolean trebuie s ia valoarea true dac se dorete ca datele s fie adugate la sfritul unui fiier existent. Ca i n cazul altor clase de scriere n fluxuri, trebuie s avei grij s nu suprascriei accidental un fiier existent. Clasa FileWriter conine trei metode ce pot fi folosite pentru a scrie date ntr-un flux: write(int) Scrie un caracter. write(char [], int, int) Scrie caracterele din tabloul specificat, ncepnd de la poziia dat i avnd numrul de caractere dat. write(String, int, int) Scrie caractere din irul specificat, ncepnd de la poziia dat i avnd numrul de caractere dat. Urmtorul exemplu scrie un flux de caractere ntr-un fiier folosind clasa FileWriter i metoda write (int): FileWriter litere = new FileWriter("alfabet.txt"); for (int i = 65; i < 91; i++) litere.write((char)i) ; litere.close() ; Metoda close () este folosit pentru nchiderea fluxului, dup ce toate caracterele au fost trimise n fiierul destinaie. lat coninutul fiierului alfabet.txt produs de acest cod: ABCDEFGHIJKLMNOPQRSTUVXYZ Clasa BufferedWriter poate fi folosit pentru scrierea ntr-un flux de caractere cu zon tampon. Obiectele acestei clase sunt create folosind constructorul BufferedWriter (Writer) sau BufferedWriter (Writer, int). Argumentul Writer poate fi oricare dintre clasele de fluxuri de caractere de ieire, cum ar fi FileWriter. Al doilea argument, opional, este o valoare ntreag ce indic dimensiunea zonei tampon care va fi folosit. BufferedWriter posed aceleai trei metode de ieire ca i FileWriter: write(int), write(char[], int, int) i write(String, int, int). 0 alt metod folositoare este newLine (), care trimite caracterul (sau caracterele) ce specific sfritul liniei pe platforma folosit pentru rularea programului.

Diferitele caractere de sfrit de linie pot crea neplceri la transferul unui fiier de pe un sistem de operare pe altul, cum ar fi cazul cnd un utilizator Windows 95 copiaz un fiier pe un server Web care folosete sistemul de operare Linux. Folosind metoda newLine() n loc de un literal (cum ar fi '\n'), putei utiliza programul dumneavoastr pe diferite platforme. Metoda close () este apelat pentru a nchide fluxul de caractere de ieire i pentru a asigura c toate datele memorate n zona tampon au fost trimise ctre destinaia fluxului.

Filtre de fiiere i de nume de fiiere


n toate exemplele de pn acum, pentru referirea la numele fiierului implicat ntr-o operaie cu fluxuri s-a folosit un ir. De multe ori, acest lucru este suficient, ns dac dorii s copiai, s redenumii sau s realizai alte activiti cu fiiere, putei folosi i obiecte de tip File. Clasa File, care face i ea parte din pachetul java.io, reprezint o referin ctre un fiier sau un director. Pot fi folosii urmtorii constructori File: File ( String) Creeaz un obiect File pentru directorul specificat - nu este indicat nici un nume de fiier, deci acesta se refer doar la un director. File(String, String) Creeaz un obiect File pentru directorul specificat i pentru fiierul cu numele specificat. File(File, String) Creeaz un obiect File a crui cale este specificat de obiectul File i al crui nume este dat de irul specificat. ntr-un obiect de tip File putei apela mai multe metode folositoare. Metoda exists () returneaz o valoare boolean care arat dac fiierul exist sub numele i n directorul specificate la crearea obiectului File. Dac fiierul exist, putei folosi metoda length(), care retumeaz o valoare de tip ntreg long ce reprezint dimensiunea fiierului n octei. Metoda renameTo (File) redenumete fiierul sub numele specificat de argumentul File. Se retumeaz o valoare boolean, care indic dac operaia s-a finalizat cu succes sau nu. Metoda delete () sau deleteOnExit () se apeleaz pentru tergerea unui fiier sau a unui folder. Metoda delete () ncearc s fac imediat tergerea (i returneaz o valoare boolean care indic succesul operaiei). Metoda deleteOnExit () ateapt i ncearc s tearg fiierul dup ce restul programului i-a terminat execuia. Aceast metod nu retumeaz nici o valoare iar programul trebuie s se termine la un moment dat pentru ca metoda s funcioneze. Metoda mkdir () se folosete pentru a crea un director specificat de obiectul File pentru care s-a apelat. Aceasta retumeaz o valoare boolean care indic succesul sau eecul operaiei. Nu exist o metod echivalent pentru tergerea directoarelor, deoarece metoda delete () poate fi folosit la fel de bine i pentru directoare i pentru fiiere. Ca n cazul tuturor operaiilor care implic lucrul cu fiiere, aceste metode trebuie folosite cu grij pentru a evita tergerea unor fiiere sau directoare sau suprascrierea unor fiiere. Nu exist nici o metod pentru recuperarea fiierelor sau a directoarelor terse. Fiecare dintre aceste metode va semnala o excepie SecurityException dac programul nu are permisiunile necesare pentru executarea operaiilor respective, deci trebuie folosite blocuri try. . . catch sau clauze throws pentru a trata aceste excepii.

S-ar putea să vă placă și