You are on page 1of 371
Google This book is provided in digital form with the permission of the rightsholder as part of a Google project to make the world's books discoverable online. The rightsholder has graciously given you the freedom to download all pages of this book. No additional commercial or other uses have been granted Please note that all copyrights remain reserved About Google Books Google's mission is to organize the world’s information and to make it universally accessible and useful. Google Books helps readers discover the world’s books while helping authors and publishers reach new audiences. You can search through the full text of this book on the web at ittp//books.google.com4 viizesy Google Daniel Danciu George Mardale ARTA PROGRAMARII IN JAVA vol I - Concepte fundamentale viizessy Google Cuprins Prezentarea limbajului Java Ml 12 13 14 1s Nofiuni fundamentale de programat 2 22 23 24 imbaje de programare . {nceputusile imbajului Java Caracteristici ale limbajului Java Implementiri ale limbajului Java Implementarea Sun a limbajului Java 1.5.1 Platformele Java : 1.5.2. Platforma J2SE (lava 2 Platform, Standard Edition) 1.5.3 I2SDK Java 2 SDK, Standard Edition) 1.54 J2RE (ava 2 Runtime Environment, Standard Edition) 1.5.5 Documentatia J2SE (Java 2 Standard Edition Documen- tation) 1.5.6 Licenja de utilizare a platformei J2SE Java ‘Mediu! de Iueru Java Primul program Java 2.2.1 Comentarii 2.22 Funcjiamain 2.2.3 Afigarea pe ecran Tipuri de date primitive 2.3.1 Tipurile primitive 23.2 Constante . 2.3.3 Declararea si inijalizarea tipurilor primitive in Java 2.34 Citite/scriere Ia terminal Operatori de baz’ 24.1 Operatori de atribuire 24.2 Operator aritmetici binari 3 7 a 19 2 2B . 26 . 26 27 29 32 32 32 34 35 35 36 37 37 37 37 38 39 40 4 . 42 cura 24.3 Operator aritmetici unati Conversii de ip 25 ini conditionale 25.1 Operator relajionali 25.2 Operator logict 25.3 Operator la nivel de bit 25.4 Instrucjiumea S 25.5 Instructiunea while 25.6 Instructiunea for 25.7 Instructiunea do 25.8 Instructiunile break si continue 25.9 Instrucjiunea switch . 2.5.10 Operatorul conditional 2.6 Meiode . 2... ce eeeee 26.1 Supraincirearea numelor la metode Referinte 31 Ce este oreferin . : 3.2 Fundamente despre obiecte si referinje 3.2.1 Operatorul punct (.) 3.2.2 Declararea obiectelor 3.2.3 Colectarea de gunoaie (garbage collection) 3.2.4 Semnificatia operatonutu 3.2.5 Transmiterea de parametsi 3.2.6 Semnificajia operatorului 3.2.7 Supraincdrcatea operatorilor pentru obiecte . 3.3. Siruri de caractere (stringuri) 3.3.1 Fundamentele utiliziii stringurilor 3.3.2 Concatenarea stringurilor 33.3 Compararea stringurilor 33.4 Alte metode pentru stringuri . . 3.3.5 Conversia de la string la tipusile primitive si invers 34. Sinai 34.1 Declarajie,atribuire si metode 34.2 Expansiunea dinamici a girurilor 34.3. $inuri cu mai multe dimensiuni 34.4 Argumente in linie de comand 42 4B aEEE 49 sl . SI 2 33 . 54 56 . 56 . ST 67 ao 68 a) 70 n n R 2 .B “ 18 9 BREE 4 Obiecte si clase 4.1. Ce este programarea orientata pe obiecte? 4.2 Unexemplu simplu 43° Metode zuale 4.3.1 Constructor Modificatori si accesori Afigare gi toString () Metoda equals () Metode statice Auribute statice . Metoda main () 44 cece Directiva import. Instructiunea package Variabila sistem CLASSPATH Reguli de vizibilitate package-friendly Compilarea separati 4.5 Alte operatiicu obiecte gi clase 4.5.1 Referinja this 4.5.2. Prescurtarea this pentru constructor: 4.53 Operatorul instanceof . 4.54 Inigializator statici S Mostenire SAL Ce este mostenirea? 5.2 Simaxa de bazii Java 5.2.1 Reguli de vizibilitate - : 5.22 Constructorsisuper ...... 5.23 Redefinirea metodelor, Polimorfis 5.24 Redefinirea parfiala a metodelor 5.25 Metode si clase final 5.26 Metode gi clase abstracte 5.3 Exemplu: Extinderea clasei Shape 54 Mostenine multipla 55. Interfeje 5.5.1 Definirea unei interfeye 5.5.2 Implementarea unei interfeje 5.53 _Interfeje multiple . 5.6 Implementarea de componente generice 37 BSSEss 98 -101 -101 102 103 103 105 106 106 106 108 = 108: 108: 1s 6 119 -120 -120 2122 128 128 130 133 138 139 139 139 1d sd 2145; 5.7.1 Clasificarea claselor interioare . 5.7.2 Clasele membre statice ale clase exterioare 5.7.3 Clasele membre nestatice ale clasei exterioare 5.7.4 Clase locale 5.7.5 Clase anonime . : 5.7.6 _Avantajele si dezavantajeleclaselorimerioare 5.8 Identificareatipurilor de date in faza de execusie 58.1 Identificarea standard a tipurilor de date 5.8.2. Mecanismul de reflectic 6 Tratarea exceptilor 6.1 Ce sunt excepfiile? 6.2 Tipuri deexceptii . 6.3 Definirea proprilor exceptii de cite programator 64 Prinderea si tratarea exceptilor 64.1 Blocul try 64.2 Blocul catch 643 Blocul finally 6.5 Anuncarea excepfiilor 65.1 Instructiunea throw 65.2 Clauza throws 6.46 Sugesti pentru uilizarea ficient a exceptilor | 6.7 Avantajele uilizirii excepyiilor. Coneluzii 7 Intrare si iesire (Jay 7.1 Preliminari 7.2 Operatii de baz pe Muxuri (stream-uri) 7.3 Obiectul StringTokenizer 74. Fisiere secventiale 75 Utilizarea coletilor de resurse (resource bundles) 75.1 Utilizarea fisierelor de proprietiti pentru citirea datelor vO) 8 Firede executie 8.1 Ce este un fir de executie? 8.2 Fire de execusie in Java 8.2.1 Crearea firelor de execusie 8.3 Accesul concurent la resurse 83.1 Sineronizare 83.2 Capcana metodelor nesincronizate 83.3 Instrucjiunea synchronized . -1St 151 153 153 156 159 160 163 165 178 178 = 180) 183 186 186 -187 191 195 195 2197 200 204 207 208, = 209 210 212 212 216 27 2218 2218, 222 229 233, 235 84 83.4 Competijie asupra monitoarelor . 8.35. Sincronizarea metodelor statice 8.3.6 Monitoare si atribute publice 8.3.7 Cind NU trebuie si folosim sineronizarea 8.38 Blocare circulari (deadlock) Coordonarea frelor de execujie. eee 84.1 De ce este necesar si coordonam firele de execusie? 842 wait() sinotity() 8.4.3 Exemplu de coordonate a firelor de execusie: problema consumator-producitor 8.44 Dejinerea monitoarelor 84.5 Utilizarea instru 8.4.6 Unalt exemplu: consumator si producitori multipli 84.7 Utilizarea lui InterruptedExcept ion A. Mediul Java gi uneltele ajutitoare Asl Bditarea codului sursi ALLL Editoare : A.L2. Meditintegeate IDE (Integrated Development Environ- ‘ments) A2 Instalarea mediului Java A2.1 Instalarea sub Windows A241 Instructiuni de instalare A.22Instalarea sub Linux A221 _Instrucjiuni de instalare A22.2 _Instalare cu autoextragere A223 Instalarea folosind RPM A3. Compilarea codului sursit ABA Ant AA Rularea unei aplicaii java Ad CLASSPATH AS Documentaii java . B_Conventii de notafiein Java. Utilitarul javadoc B.1Necesitatea conventiilor de scriere a programelor B.2 Tipuri de fisiere B.3 Organizarea fisierelor sursi java B3.1 Comentarile de inceput B3.2_ Instructiunile package gi import B.3.3._Declarapile clasi si interfejei 237 237 239 239 240 242 242 2244 24s 250 251 255 238 265 265 265 266 267 268 268. 270 :270 2 2m. 273 75 2 .277 2278 279 279 280 280 281 281 +282 Ba Indentarea..... . wee eee 9283 B4.1 Lungimeaunei linii de cod... oe 284 B42 "Ruperea' linilor 284 B43 Acoladele 284 B44 Spaierea 285 BS Comentarile 286 B.S.1 Comentarii de implementare 287 B52 Comentarile de documentajie 288 B6 Declariti . wees = 288) B61 Numirul de declariri pe linie . . . wee 2 288 B62 Inifilizarea variabilelor . 6. 289 B63. Loculdedeclararea variabilelor ... 289 B64 Declararea claselor sia interfojelor. ...... 289 BT Instrucyiuni 290 B.7.L _Insteucyiuni simple 290 B.7.2_ Instrucfiuni compuse 290 B73 Instrucfiunea return 291 B74 Instructiunea if-else 291 B75 Instructiunea for 292 B76 Instructiunea while 2. . 292, B77 Instrucjiuneado-while ....... 2.292 B78 Instrucjiunea switch ..... 2... 22.292 B79 Instrucjiunea try-catoh...... 2. 293 B8 Convengii de notatie . feet eee ees 2294 BO. Practici utile in programare 296 9.1 Referizea atributelor $i a metodelor statice 296 B92 Atibuirea de valori variabilelor 297 B.10 Exempla de figiersursi Java 297 BAI Utilitarul javadoc 299 B.IL1 Sintaxa javadoc 299 B.LI2 Deserierea wtilitarslui 300 B.L13 Btichete javadoc +. 303 B.114 Opjiunile comenzii javadoc»... . 25. 305 -307 C Definirea pachetelor Java, Arhive jar 310 CL Prezentare generaliia pachetelor Java predefinite 310 C2 Definirea de pachete de catre utlizator . . wee BIE C3. Athive jar (ava ARchives) 0 eee 322 C3. Utilizarea fisierelor . jar 2323) 3.2 Crearea unui figier jar... - duoapaooeys) 3.3. Vizualizarea conjinuiului unui fisier . jar oe 327 C34 Extragerea conjinutului unuifigier jar... .... 328 C35. Figioral manifest al unci arhive ar... 0... 329 €3.6 Modificarea figienului manifest al unciarhive jar. . . 331 €3.7 Modificarea conjinutului unui fier . jar 332 C38. Rularea aplicatilor Java "impachetate” int-o arhiva jar 333 D_Internafionalizarea aplicafiilor. Colecfii de resurse 335 Dal Timpul, numerele sidatele calendaristice. ss... 335 D2. Colectile de resurse in intemnajionalizarea aplicayiilor .. . . . . 341 2.1 Unexempluconcret.. . . cee 2 342, 22 Implementareacoleflorprin Li stResourceBundie344 D.2.3 Implementarea colecjilorprin Proper tyResourceBundle36 D.24 Utilizarea colectillorde resurse . ov ee 348 D3 Imternationalizarea mesajelor dinamice .. . «ss ss ss +» «351 E_ Resurse Java 356 ELL Site-ul Sun Microsystems . 356 E2_ Tutoriale despre limbajul Java disponibile pe Internet 337 3 Cagji despre limbajul Java disponibile pe Internet 357 Ed Reviste online de specialitate oe vee vv es 358 ES Liste de discufii despre limbajul Java... 6... vos ss ss 358 EG Alte resurse ava ee ee 389 viizessy Google Introducere Ce invitur pred Macstal?” seb un vziator ‘Nici una”, rispunse discipoll “Atunci de ce fine discursuri?” “Bl doar ne ara calea- nu ne vai nimi.” “Anthony de Mello, O clip de injlepciune icine a folosit cel pugin o data Internet sau acitito revisté de specalitate {n domeniu! informaticii, a auzitcu siguranga cuvantal Java. Java reprezintd un limbaj de programare, creat de compania Sun Microsystems in anul 1995. Initial Java a fost gndit petra a imbunatai continutul paginilor web prin adau- garea unui conginut dinamic: animaie, multimedia ete. In momentul lansérit sale, Java a revolujionat Internet, deoarece era prima tehnologic care oferea un astfel de conjinut. Ulterior au aparut gi alte tchnologii aseménatoare (cum ar fi Microsoft ActiveX sau Macromedia Shockwave!), dar Java gi-a pistrat importanja deosebité pe care a dobindit-o in rindul programatorior, in primul rind datortéfacilitilor pe care le oferea. incepand eu anul 1998, end a aparut versiunea 2a limbajului (engl. Java 2 Platform), Java a fost extins, acoperind gi ate diree{i de dezvoltare: programarea apical enterprise (aplicaii de tip server), precum gi a celor adresate dispo7i telefoane mobile, pager-e sau PDA-usi®. Toate acestea au reprezentat facili jelor eu resurse limitate, cum ar fi Goi cre wine mal des Itercal sunt probabil big cu contoale ActiveX sau ev ai ‘mai lash adel paginilor web. 2PDA = Personal Digital Assistant (mick dspotive de eau, de dimensiuni pun mal mas ect ale uni telefon mobi capable st ofee fit de agen, dar is uleze apical it-an od ea asemanitor cu celal unui PC)-La moment actual exist:mal mute pus de PDA. Plm-u, pockelPC-u n roi adiugate limbajului, care a pistrat insé si posiblitiile de a crea aplicait standard, de tipul aplicaiilor in linie de comands sau aplicaii bazate pe GUE. Lansarea versiunii 2 a limbajului Java a fost 0 dovada a succesului imens de care s-au bucurat versiunile anterioare ale limbajului, da sia dezvoltari limba- Jjului in sine, a evolufici sale ascendente din punct de vedere al fa care le ofera, cat si al performangelor pe care le realizeaza Cum este organizatit aceasta carte? Avand in vedere popularitatea extraordinari de care se bucuralimbajul Java in cadnul programatorilor din intreaga lume, am considerat util scrierea une lucrari in limba romana care si fie accesibila celor care dorese si fnveje sau sit aprofundeze acest limbaj. Ideea care a stat la baza realiztiiacestei cari a fost aceea de a prezenta nu numai limbajul Java in sine, ci si modul in eare se implementeaza algoritmii si structurile de date fundamentale in Java, elemente care sunt indispensable orietirui programator eu pretengii..Agadar, cartea nu este destinati numai celor care dorese si acumuleze nofiuni despre limbajul Java in sine, ci i celor care intenjioneaza si igi aprofundeze gi rafineze cunos- tinjele despre algoritmi si si igi dezvolte un stil de programare elegant. Ca 0 consecing, am structurat cartea in douti volume: prima volum (cel de fafa) este orientat spre prezentarea principalelor caracteristici ae limbajului Java, in timp ce volumul al doilea (disponibil separat) constituie oabordare a algoritmilor din perspectiva limbajului Java, Finalul primului volum cuprinde un grup de cinei ‘anexe, care prezint mai aminunjit anumite informatii cu caracter mai special, deosebit de utile pentru cei care ajung s& programeze in Java, Am ales aceasta strategie deoarece a doblndi cunostinje despre limbajul Java, fri a avea o ima- gine clara despre algoritmi, nu reprezint& un progres real pentru un programator, Iarscopul nostru este acela de a va oferi posibilitatea si deveniti un programator pentru care limbajul Java gi algoritmi si nu mai constituie © necunoscut Cele dou volume cuprind numeroase soluji Java complete ale problemelor prezentate, Mai este necesarl o remarci: deseori am optat, ait in redactarea co- etc.). in Java, operatori de egalitatefinegalitate sunt == respectiv !=, De exempla, exprStanga == exprDreapta are valoarea true daci exprStanga si exprDreapta suntegale, altel are valoarea fa1se. Analog, expresia: exprStange != exprDeeapta are valoarea true dact exprStanga si exprDreapta sunt diferite altfel are valoarea false. Operatorii de comparatie sunt <, <=, >, >= iar semnificayia lor este cea na- ‘ural pentru tipurile fundamentale, Operatorii de comparajic au prioritate mai ‘mare decit operatorii de egalitate, Totusi, ambele categorii au prioritate mai ‘mic& decat operatoriiaritmetici, dar mai mare decat operatori de atribuire. Ast- fel, vejiconstata ei in cele mai multe cazurifolosirea parantezelor nu va fi nece- sari, Toji acesti operatori se evalueaza de la stinga la dreapta, dar cunoasterea acestui lucru nu ne foloseste prea mult. De exemplu, in expresia a > << >>> © operatorilogici: & | ~~ Fie cd fac parte din prima sau a doua categorie, operatori la nivel de bit nu pot fi utilizagi decat in cazul numerelor intregi (variabile de tipul byte, short, int si long). De fapt, operatorii se aplicd reprezentirii binare a numerelor implicate. Cu alte cuvinte, dact avem operajiaS & 3, aceasta inseamn’ cl de fapt operatorul & se aplicd reprezentiri in baza 2 a numerelor 5 si 3, adied 101 sill Prima grupii de operator la nivel debit, cea a operatorilor de deplasare, exe- cut manipularea bitilor primului operand, deplasindu-i la stinga sau la dreapta, {n funcjie de tipul operatorului (vezi Tabela 2.3), Tabela 2.3: Operator la nivel de bit pentru deplasare (operator [Uilizare —_[ Deseriere ] SS | opl>>op2 | deplasarca biflor lar opl Ta dreapta cu 0p2 poziti <<] opl<>> op2 | deplasarea biilor lui opt Ta dreapia eu op? poritii, opl fiind considerat unsigned scare operator deplaseazi bifii operandului din stinga cu un numér de po- Ziti indicat de operandul din dreapta. Deplasarea se face perator (>> Ia dreapta, iar << la stinga). De exemplu, urmitoarea instrucjiune ‘deplaseaza bit numarului§ la dreapta cu o poritie: sensul indicat de o- 5 >> Reprezentarea binari a numirului 5 este 101. Prin deplasarea bifilor la dreapta cu o pozitie se objine numirul care are reprezentareabinarii 10, deoarece primul 1 (cel din stinga) trece cu o pozitie mai la dreapta, deci in locul lui 0, care trece cu 0 pozitie mai la dreapta, deci in locul celei de-a doua cifre 1, 46 2.5. INSTRUCTIUNI CONDITIONALE care se pierde, Bitii din stanga care au rimas descompletaji se completeaza cu 0, ceea ce conduce Ia rezultatul final O10, Astfel, am objinut numarul 2 in reprezentarea zecimali. inconcluzie,5 >> 1 = 2. DupAcum se poate observa, pentru numerele povitive, deplasarea Ia dreapta cu. op2 bifi este echivalenté cu imp&rtirea Tui (op! Ia 2°°2, Pentru exemplul nostru, 5/2! = 2. ‘Analog se intémpl si in cazul deplasieii la stinga. Instrucfiunea urmatoare eplaseazd bitii numirului 5, la stinga, eu 0 pozifie: sca; Rezultatul deplasiri bisilor 101 la stinga cu o pozifie este 1010, adic ‘numrul 10 in reprezentare zecimala. Acest cru este echivalent cu inmuljiea cu 2°72. in cazul nostra, 5 +2! = 10. Col de-al treilea tip de deplasare a bitilor, >>>, este asemanatorcu >>, cu specificarea ci numarul op1 este considerat firé semn (unsigned), Cea de-a dous categorie de operator la nivel de bit realizeaza operafiilogice SI, SAU, SAU EXCLUSIV (XOR) si NEGARE: ‘Tabela 2.4; Operatori pentru operatiilogice la nivel de bit ([Opentor [Uiizare Deseriere ] © [opt & op? Goniverdetip T [opt top2 SAU Tove de i 7 [opt * op2_| SAU EXCLUSIV la nivel dei = =apt | NEGARE Ta nivel debi ‘Si presupunem cit avem dou’ numere, 5 si 3, elrora dorim si le aplicim ‘operatiilogice la nivel de biti. Operaiie logice la nivel de bificonstau in apli- carea operafiei respective perechilor de biti de pe pozitit egale in ele douk rnumere (cu excepfia operajiei de negare care este unari). in situajia in care nu- mmerele nu au reprezentarea binarii de aceeasi lungime, reprezentarea mai seurti este completati cu zerouri nesemnificative (inserate in fafa reprezentiri), pan’ se objin dimensiuni egale. Prezentate pe scurt, operatile logice pe perechi de biti se realizeaza pe baza uurmatorului alogritm: 47 25, INSTRUCTIUNI CONDITIONALE © expresia bl & b2 are valoarea 1, daca gi numai dacit b1 gi b2 au var loarea 1 (b1 si b2 sunt 2 biti, care pot lua, evident, doar valorile 0 gi 1). Alltfel, expresia are valoarea’ © expresia bi. | 2 are valoarea 0, daci gi numai dac bi si b2 au valoa- rea 0. Altel, expresia are valoarea |; © expresia bl ~ b2 are valoarea I, dacd gi numai daca unul dintre ope- ranzi este 0, iar celilalt 1. Altfel, expresia are valoarea 0; © expresia ~b1 reprezinti negarea lui b1, dei are valoarea 1, da 0, sau are valoarea 0, daci b1 este 1 Tati citeva exemple de utilizare: e5e3e1 Was H=3 " as a3 Meat os 73-6 as a3 ns e753 - 6 - Wes yas 48 2.5, INSTRUCTIUNI CONDITIONALE Aceasti operajie necesit anumite precizari, Dup cum am vizut ante- rior, un numar de tip int este reprezentat pe 32 de bij. Cu alte cuvinte, reprezentarea numérului 5 in baza 2, are de fapt 32 de cifre binare, dintre care 29 sunt zerouri nesemnificative (cele din fafa), pe care le-am omis, pina acum din motive de spatiu. La 0 operatie de negare, toate zerourile rnesemnificative ale reprezentiriibinare devin I si capata astfel important (primul bit este bitul de semn, care se modificd gi el). Pentru a injelege ‘mai bine modul in care se reprezinti numerele intregi in memorie vi re comandaim lucrarea [Boian) 2.5.4 Instruefiunea i Instructiunea 4 £ este instructiunea fundamental de decizie. Forma sa sim- plieste: LEE (expeesie) Surmatoarealnstructivne Dac expresie are valoarea true atunci se executa instructiune; in caz contra, instructiune nu se executi, Dupi ce instrucjiunea if se incheie fara incidente (vezi cazul excepjiilor netraate, in capitolul 6), controlul ste preluat de urmatoareaTnstructiune, Optional, putem folosi instructiunea if-e1se dupa cum urmeazi HAE Cexpresie) 2 instevetivael pelae 1 instructiune? in acest caz, dact expresie are valoarea true, atunci se executi ins- tructiunel; altfel se executt instructiune2. In ambele cazuri con- twolul este apoi preluat de urmatoareaInstruct iune, lati un exemplu: » System out. p Hit (xt 0) y System out. print ( 1/x )s System. out. print ( tin ("17x este edefint 4 System. out. printia (): De reinut c& doar o singurd instructiune poate exista pe ramura de £ sau de else indiferent de cum indentafi codul. Iat& dou’ erori frecvente pentru 49 25, INSTRUCTIUNI CONDITIONALE {incepatori: Vif (x == 0) 5 instructinne vida tt + System.out. printin("s este 0"): relae 4)" system. out. print ("x este"): 5 System-out. println(x): //Instructiume in afara clause! else Prima greseali consti in a pune ; dupi ££. Simbolul ; reprezinti in sine instructiunea vide; ea 0 consecin{, acest fragment de cod nu va fi compilabil (else nu va fi asociat cu nici un if). Dupi ce am corectat aceasti eroare, rimdnem cu o eroare de logici: ultima linie de cod nu face parte din i£, desi acest lueru este sugerat de indentare. Pentru a rezolva aceasti problema vom utiliza un bloc in care grupim o seevenfi de instructiuni printr-o pereche de acolade: 5) System.out. print ("x este): {System out. println(x) " Practic, prin cuprinderea mai multor instrucjiuni intee acolade, cream 0 sin- uri instructiune, numiti instrucfiune compusd, Asadar, instruct iunel (casi instruct iune2) poate fo instructiune simpla sau o instrucjiune com- pus’, Instructiunile compuse sunt formate dintr-o succesiune de instrucfiuni (simple sau compuse) cuprinse intre acoloade. Aceasta definiie permite imbri- carea instructiunilor compuse in cadrul altorinstrucjiuni compuse. in exemplul anterior, pe ramura if avem o instructiune compusi formati doar dintr- sin- urd instructiune simple System-out. printia("x este 0"): ” ‘Am folosit aici o instrucyiune compusi desi, flind vorba de o singuri in- strucfiune simpli, acest lueru nu era absolut necesar. Totusi, aceasta practic’ imbunitieste foarte mult lizibilitatea codului gi va invitim gi pe dumneavoas- 18 st o adopragi Instrucfiunea i £ poate si faci parte dintr-o alti instructiune ££ sau else, la fel ca si celelate instrucjiuni de control prezentate in continuate in aceast 2.5, INSTRUCTIUNI CONDITIONALE 2.5.5 Instruetiunea while Java, ca gi Paseal sau C, dispune de tre instructiuni de ciclare (repetitive) instructiunea while, instructiunea do gi instrucjiunea for. Sintaxa instructiunit whi Le este: while (expresie) ‘urmatoarealnstructivne Observati ed, Ia fel ca gi la instructiunea if, nu exist apareun ; dupa while, va fi considerat ca instructiune vida. Cat timp expresie este true se execut instructiune; apoi ex- presie este evaluat din nou, Daci expresie este false de la bun in- ceput, atunci instructiune mu va fi executata niciodaté. in general, in- struct {une face o acfiune care ar putea modifica valoarea lui expresie: altel, ciclarea s-ar putea produce Ia infinit. Cand executia instructiunii whi le se Incheie, controlul este preluat de urmatoareaTnstructiune, 2.5.6 Instruetiunea for Instrucjiunea whi le ar fi suficienta pentru a exprima orice fel de ciclare. ‘Totusi, Java mai ofera inci doua forme de a realiza ciclarea: instruejiunea for si instrucjiunea do, Instrucjiunea for este utilizaté in primul rind pentru a realiza iteraja. Sintaxa ei este sfor (initializare; test; aetualizare) ‘uematourealnstructiune fnaceast situate, initializare, test siactualizare sunttoate cexpresi gi toate tei sunt opfionale. Daci test lipsese,valoarea sa implicit este true, Dupt paranteza deinchidere nu se pune ; Tnstruefiunea for se executérealizénd mai inti initializare. Apoi, cat timp test este true se executi instruct iune, iar apoi se executi actualizare, Daci initializare si actualizare sunt omise,in- Strufiunea for se va comport exact casi instrucjiunea whi Le ‘Avantajulinsruiunii For const in faptl ef se poate vedeaclar mara pe care itereazi varabilele contr. ‘Urmitoaren secvenfi de cod afigeazprimele 100 mumere integipozitive Hor (int 1 = 1: 4 < 100: +44) H si 25, INSTRUCTIUNI CONDITIONALE » System. out. printin (i): “a ‘Acest fragment ilustreaz si practica obignuiti pentru programatorii Java (si (C++) de a dectara un contor intr in secvenfa de iniializare a ciclului. Durata de viaji'a acestui contor se extinde doar in interionul ciclului. Ait initializare cit $i actualizare pot folosi operatonul virgula! pentru a permite expresii multiple. Urmitorul fragment ilustreazi aceasti tebnic’ freevent folosti for (i = 0, sum = 0; 1 fi )System.out. printing + "\e" + sum) a +, sum +20) Ciclurile pot fl imbricate la fel ca si instructiunile i. De exemplu, putem siisi toate perechile de numere mici a c&ror sumé este egal cu produsul lor (cum ar fi si2, a ciror suma si produs este 4) folosind secvenja de cod de mai jos: Hor (int i = 1; i <= 10; i44) for (int j = 15 5 c > 0; j48) el es ben ( System.out. printin(i #7." + 5): 2.5.7 Instrucfiunea do Insiricfiunca white realizeard un test repetat, acd test este true atunci se executtinstructiunea din cadrul ei Totus, dacé tet iia este instrucinea din cadrul ciclului nu este executata niciodata, In anu tii avem nevoie ca instrctunile din ciclu s& se execute cel putin 0 dati, Acest hrs se poste relia uilizénd instrcjinea do. Insretiunea do cst aseminitoare ct insiructunea wh’ Le, ou doosebireac8tstl est realizat dupi ce instrutiunile din corpuleiculu se exeeut. Simtaxa sa est: do 3 white expresie J urmatoareainstructinne 2 2.5. INSTRUCTIUNI CONDITIONALE Remarcagi faptul c& instructiunea do se termind cu ;. Un exemplu tipic in care se utilizeaza instrucjiunea do este dat de fragmentul de (pseudo-) cod de mai jos: afiseaza_mesaj: (data au este corecta): Instructiunea do este instructiunea de ciclare cel mai putin utlizaté, Totusi, nd vrem si executaim cel pusin o data instrucjiunile din cadrul cicluli, si for este incomod de utilizat,atunci do este alegerea potrivita 25.8 Instructiunile break si continue Instrucjiunile for gi while au condijia de terminare inaintea instructiu- nilor care se repeti. Instructiunea do are condifia de terminare dupa instructi- unile care se repeti. Totusi, in anumite situa, s-ar putea si fle nevoie si in- trerupem ciclul chia mijlocl instrcfiunilor care ve repeti. tn acest seop. se poate foloiinsticfiunea break. De obcei, instrcfiunea break apare in cadruluneiinstruiuni ££, an exemplal de mai jos: white (...) + Uf (conditiey 4 5 break: fn cazul in care sunt doua ciclriimbricate, instucfiunea break partseste doar cilul cel mai din interior. Dacd exist mai malt de un cicla eae tebuie terminal, break mu va funcfiona corect, gi mai mult ea sigur ci ai proiectat prostalgoritml, Tosi, Java oferd aga numitl break etichetat. in acest exz, 6 anumitéinstractune de ciclare este etichetaa i insnicjiunea break poate fl aplicatd aceeiinstrucjuni de ciclare indiferent de numul de cicluriimbricat Tat un exemplu ee nlte (..) ani 5 white (...) : Hi 3 25, INSTRUCTIUNI CONDITIONALE i it (conditie) zl i 3 break cticheta . , * , Boy h//controtul programului trece aici dupa executia Iwi break in anumite situaii dorim si renunjim la executia iterafici curente din ciclu si si trecem Ia urmitoarea iterajie a ciclului. Acest luera poate fi realizat cu instructiunea continue. Ca si break, instrucfiunea continue este urmatt de ; si se aplic& doar ciclului cel mai interior in eazul ciclurilor imbricate Urmitorul fragment tipireste primele 100 de numere intregi, cu exceptia celor ivizibile eu 10: Hfor (int i = 1; i <= 100; 149) a iri @ 10 c System. out. printin (i): Desigur, ei exemplul de mai sus poate fi implementat si uilizind un i£ simplu. Totusi instructiunea cont inue este adeseori folosité pentru a evita imbricdri complicate de tip if -e1 se in eadrul ciclurilor. 25.9 Instructiunea switch Instructiunea switch este numitii uneor si instructiune de selectie; ea are rolul de a selecta dintre mai multe seevenje de cod, una care va fi executati, funcjie de valoarea unei expresiiintregi. Forma sa este switch (Cexpresiemselectare) t case valoare—in gel break; valoare-intreaga? breaks sow tense valoare-introngaN 34 2.5, INSTRUCTIUNI CONDITIONALE * break: DC aetaute " expresie-selectare este o expresie care produce o valoareintreag Instrucfiunea switch compari valoarea expresiei expresie-selectare eu fiecare valoare-intreaga. Daci are loc egalitata, se executh instructi- unea corespunzitoare (simpli sau compust), Dac nu are loc nico egalitate se executt instrucjiunea din def aul (alterativa default este opjionald in cadral switch). ‘Observasi ein exemplul de mai sus, fiecare case se incheie cu un break care are ca efect saltl la sfirgitul instrujiunii switch. Acesta este modul obignuit de a serie o instrucjiune de tip switch, dar prezenfa instruciunit break nu este obligatorie, Dact instrucjunea break lipseste, atunci se va ‘execu si codul corespunzitorinstucjunilor case urmatoare pant cind se fn- talneste un break. Desi de obicei nu ne dorim un astel de comportament, el poate fi uncor’ util pentru programatori experimenta Pentru a exemplfica instruciunea switch, programul din Listing 2.3 ere- a7 litere aleator si determina dact acestca sunt vocale sau consoane (in limba englezi. ing 2.3: Program care exemplified instrucjiunea switch 1 TVowelsAndConsonants fa 2 // Program demonstratiy pentra instructiunea switch ) public. class VowelsAndConsonants public statte void main(String [1 ares) of FS for (int i = 0: 1 < 100; 144) eo : har c= (char) (Math, random () #26 + 'a"): “ System -out-print(e # "2 ")s " switch (©) s i 5 ‘System out. printin (*vocala"): 7 break: > ease "y! 35 26 METODE System. out. printin("Uneori vocale *): “doar in limba engleza! x break: a default = ‘System. out. priatla(“consoana" ): 7 ) /switen ") Ufor =| main >) Helass Funcjia lath .random() genereazi ovaloare in interval 0,1). Prin ine 1olfea valor returate de aceasta fnctie ca numa de litre din afabet (26 liter) se obyne un num in interval (0,26). Adunarea cu prima liter ("a care are de fap valoarea 97, codul ASCII al iteei a’) ae ca efectranspunerea {in inervaul[97,123). tn inal se flosest operatorl de conversie de tip pen- ta trinchia nemarul a ovaloare din muimea 97,98, .. 122, adi un cod ASCII al unui caactr din alfabetul englez 2.5.10 Operatorul conditional Operatorul conditional este folosit ca o prescurtare pentru insteucsiuni sim- ple de tipul if -e1 se. Forma sa general este: expeTest ? expresieDa + expresieNu: Mai imtai se evalueaz expr Test urmati fie de evaluarea lui expresieDa fie de cea a lui expresieNu, rezultind astfel valoarea intregii expresii. ex- presieba este evaluati dacd expr Test are valoarea true; in caz contrar se evalucazl expres ieNu. Prioritatea operatorilui conditional este chiar dea- supra operatorilorde atribuire. Acestlucru permite omiterea parantezelor atunci ind asigndi rezultatal operatoralui conditional unei variable. Ca un exemplu, ‘minimul a dou variabile poate fi calculat dupa cum urmeazi vaIMin= xeytxey 2.6 Metode CCeea ce in alte limbaje de programare numeam procedura sau fancfe, fn Java este numit metoda. O defnjie complet a nojiunti de metoda o vom da tai tz, cand vom introduce nojiunile de clas i obiect. in acest paragrat prezentim doar citeva nofiun elementare penta a putea scre functi de genul ‘clor din C sau Pascal pe cares le folosim in citeva programe simple 56 Listing 2.4: Declaratea si apelul unei metode peblic clave Minin t System-out. printin ( "Minimel este: * + min(a.b) ) + 1 ms Héeclaratla metodel min public statle Int min( Int x, Int y ) a return xey?e:y 5 mod " ‘Antetel unei metode consti dint-an mume,o list (eventual vidi) de pa- rametri si un tip penta valoarea retumati. Codul efectiv al metode, mumit tdeseori compl metodei, este format dino instisjine compust (0 secveni de instuetunicuprins inte acolad). Defnirea unei metode const in atts corp. Un exemple de definite gi uti din Listing 2.4 Prin prefixarea metodelor cu ajutorul cuvintclor cheie public: static pustem mima into oarecare masurafuncfile din Pascal iC. Desi aceasta tehnic& este util in anumite situa ea n trebuie utilizta in mod abuzv. ‘Mumele metodei este un identificator. Lisa de parametri consti din 0 sau mai mulji parameriformali, fecareavind un tip precizat. Cand 0 metods este peat, paramerrit actual sunt tecu in parametri formal wilizandatibuirea obismuita. Accasta inseam c tipurile primitive sunt transmiseutlizind ex- clusi transmiterea prin valoare, Parametti actual nu vor putes fi modifica de citrefuncte. Defnirle metodelor pot apircain orice ordine. Tnstrucfiunea ret uen este utlizati pent a intoarceo valoar cite codul apelant. Dac tipulfuncyiei este void stunci nu se intoarce nici o valoare. in anumite situa, pentru iesiea fort dintvo metods care are tipul void se foloseste return; fért nici un parametm fare a unei metode este dat in programul 2.6.1 Supraincdrcarea numelor la metode ‘S& presupunem c’ dorim s& scriem o metoda care calculeaz maximul a tei ‘numere intregi. Un antet pentru aceasta metods ar fiz 7 Int max(int a, int b, Int ©) fnunetetimbaje de programare (Pascal, C), acest lueru nu arf permis dack exist deja o funcie max cu doi parametr, De exemplu, Se poate s8 avem deja dectarati o metoda max cu anetl int max(int a, int b) Java permite supraincdrcarea (engl. overloading) numelui metodclor. A- ceasta inseamnii ci mai multe metode cu acelagi nume pot fi declarate in cadrul aceleiagi clase atdta timp eat semndturile lor (adic& lista de parameti) difera ‘Atunci cAnd se face un apel al metodei mas, compilatorul poate usor si deduct despre care metodi este vorba examinnd lista parametrilor de apel. Se poate si existe metode supraincireate cu acelagi numir de parametri formali, ata timp cat cel pufin unul din ipurile din lista de paramets este diferit, De rejinut faptul c& tipul functiei nu face parte din semn’tura ei. Aceasta {nseamnd cd nu putem avea dow’ metode in cadrul aceleiagi clase care s& difere , sunt folositi pentru a decide care din 0) a > F830) " felse //else va fi asoclar ew if(a>0) ves abs + 8, Numele clasei Java trebuie fle acelasi cu numele fisienului sursi care 0 ‘confine; atengie Ia litere mari si miei 9. Lipsa instructiunit break pe ramurile logice ale instrucjiunii switch ‘duce la aparitia unui efect nedorit in cele mai multe eazuri: de la ramura ccurenti se trece la cea urmatoare care este si ea executat, Ca o consecing se executi mai multe ramuri din cadrul instrucfiunii switch, Exereifii Pescurt 1. Ce extensii folosese fisierele sursi gi cele compilate in Java? 2. Descriefi cele tre tipuri de comentarii fn Java, 43. Care sunt cele opt tipusi de date primitive in Java? 4. Care este diferenja dintre operatorii * $i *=? ‘5. Explicati diferenta dintre operatorit unari prefixati si cei postfixaf. 6. Descrieji cele tre tipuri de instructiuni de ciclare in Java. 7. Descriefi toate modurile de utilizare ale instrucjiunii bre ak. Ce fnseamna instrucjiune break etichetaté? 8. Ce face instructiunea continue? 9. Ce inseamnii suprainesirearea de metode? 10. Ce inseam’ transmiterea de parametri prin valoare? Teorie 1. Fie b cu valoarea 5 gi c cu valoarea 8. Care sunt valorile lui a, b gic ‘dupa execusia fiecdre linii de cod de mai jos? sas bit sere: sib tert sb asec 2. Care este rezultaul expresiei true && false || true? 43. Dai un exemplu pentru care ciclul £or de mai jos nu este echivalent eu ciclul whi Le de mai jos: 6 sor (init; test; actualizare) a a pwhile (rest) ut 2 actualizare:” a Indicatie in cazal in care cilul £or confine o instefiune continue, inante de a tece la urmitoare teraje se vaexecuta actualizare. 4, Pentru programul de mai jos, eare sunt valorile posibile la afgare? £ public static void main(String] args) 7 ot » int x = 0: a fo: fe System. out. printin (x): bo “) in practic’ 1, Seriefio instructiune white echivalenti cu cichil for de mai jos. Lace ar putea fi uilizat un astfel de ciclu? for(i: ) 2, Scriofi un program care afigeaz’i numerele de la | Ia 100. Modificayi apoi programul pentru a intrerupe ciclul de afigare dup’ numarul 36 folosind instructiunea break. Incercaji apoi si folosifi return in loc de break. Care este diferenja? a Scrie}i un program care genereazi tabelele pentru inmuljirea si adunarea rhumerelorcu o singurcifr Scrieji un program care si genereze 25 de valori aleatoare de tip int. Pentru fiecare valoare generatd folosijio insiructiune if-e1se pentru a determina daci este mai mic’, egali sau mai mare decit o alté valoare ‘generat aleator. Scriei un program care afigeazi toate numerele prime eu valori cuprinse intre 0 si Integer MAX_INT. Folosifi dou cicluri for (unul pentmu fiecare ‘numer si unul pentra testarea diviibilitai) si operatonul % Scrieji dou metode statice. Prima si retumeze maximul a trei numere {ntregi iar a doua maximal a patru numere intregi Scrieji o metoda staticd care primeste ea parametra un an si retumneazii ‘true daci anul este bisect si £1 se in eaz contrar. cy 3. Referinte [Noi au rejnem zie; rejinem doar rmomente, ‘Autor anonim fa capitoll 2 am prezeutattipurle primitive din Java, Toate tipurile care nu fac parte dintre cele opt tipur primitive, inelusi puri importante eum ar steingus, ii fee, sunt tipus refering fn acest capitol vorn iva: # Ceceste um tip referinj si ce este o variabilé refering; «Prin ce diferd un tip referinjé de un tip primitiv; © Exemple de tipusi referin incluzdnd stringuri si suri 3.1 Ce este o referinta? fn capitolal 2am examinat cele opt ipui primitive mpreund cu citeva o- perai care pot fi realzate pe variable van acest tipi, Toate celelaletpuri de date din Java sunt referinge. Ce este deci o refering? © variabila refering in Sava (numitd adeseori simplu referinja) este 0 variabild care refine adresa de memorie la care se afl un anumit obiect 64 ‘CEESTEOREFERINTA? Figura 3.1: Mustrarea unei referinge: Obiectul de tip Complex stocat Ia adresa ‘de memorie 1215 este referit att de cdtre nr2 ct gi de eatre nr3. Obiectul de tip Complex stocat la adresa 1420 este referit de ede ntl. Locale de memorie unde sunt refinute variabilele au fost alese arbitra, ans | 2 120 | 6.1) Ly as 2700 | ert = 1420 bpodresa 1215 sam | 221218 m2 6 “ne ee adresa 1420 13 ‘Ca un exemplu, in Figura 3.1 exist dous obiecte de tipul Complex, Pre- supunem ci aceste obiecte au fost stocate Ia adresele de memorie 1215 i res- pectiv 1420, Pentru aceste doua obiecte am definittrei referinje, nz1, nz2 si nr3. Atit nr? cit si nr3 referi (indica) obiectul stocat la adresa 1215; nz refer obiectul stocat la adresa 1420, Aceasta inseamna ci atit nx2 cit gi nz3 au valoarea 1215, iar nx1 va avea valoarea 1420, Refinefi ci locale efec- tive, cum ar fi 1215 si 1420, sunt atribuite de compilator la discrefia sa (unde giseste memorie libera). In consecing’, aceste valori nu sunt utile efectiv ca valori numerice. Totusi, faptul ci nr-2 gi nr3 au aceeasi valoare este folositor: cami ci ele refers acclagi obiect. (0 refering stocheazi intotdeauna adresa la care un anumit obiect se aff, cu ‘exceptia situatiei cind nu referd nici un obiect. In acest caz va stoca referinga ‘nul, notati fn Java cu nw. Limbajul Java nu permite referinge cdtre tipurile primitive (cum ar fi int sau float), Exist dou categori distincte de opera care se pot aplica variabilelor re- fering "Care coin parca weal ova imaginar a uni numa complex. 6s 1.1 CEESTEOREFERINTA? 1, Prima categorie permite examinarea si manipularea valori referinga. De ‘exemplu, daca modificim valoarea stocatd in nz 1 (care este 1420), putem si facem ca ny] si refereun alt obiect. Putem de asemenea compara n= 1 sinr3 pentnt a vedea daca referi acelasi obiect; 2. A doua categorie de operatii se aplic& obiectului care este referit. Am putea de exemplu examina sau modifica starea unuia dintre obiectele de tipal Comp Lex (am putea examina partea real si cea imaginara a unui obiect de tipul Complex). Accesul la oricare obiect in Java se face ex- "Sunt curajos!* 224 7 mere” Ws 2 mere" 2 este convertit la String vimere “42 > °mere 2 iran cbr stet a> abe” ‘Sirurle de caractere formate dintr-un singur caracter NU trebuie inlocuite ‘cu constante de tip caracter (constantele caracter sunt de fapt numere) Java dispune si de operatorul += pentru siruri de caractere. Efectul in- strucjiunii str += expr este str = str + expr, Cualte cuvinte str vareferi um nou String generatde str + expr ati un exemplu: sString st :String s2 = “et dsl tasds //sl va deveni “abed™ sSystem out. printia(st); //va afisa “abed” Este important si observ cd inte atibuirea: P= 6S 6 este un tntres si atribuirea: str 4 Thello? //str este um String exists 0 diferenjé esenjiali. in primul caz, varabila 5 este incrementatk cu 5; locajia de memorie a Iui 4 nu se modified. in al doiteacaz, se creazi un nou string avind valoarea stz + "hello". Dupé atibuire, st va referi acest nou string. Fost string referit va fi supus colectri de gunosie (garbage- collection) dact nu aexistato alt refering etre el. 2 {3 SIRUR! DE CARACTERE (STRINGUR) 3.3.3 Compararea stringurilor Deoarece operatorul de adunare functioneazi pe siruti de caractere, am fi tentafi si credem c& funefioneaza si operator relajionali. Acest lucra nu este ins adevarat. Conform regulii privind supraincdrcarea operatorilor, operatorii relajionali =) nu sunt definiji pentru obiecte de tip String. Mai mult, ope- 1 semnificajia clasica pentru obiecte de tip referinja (compar adrese gi nu obiecte). De exemplu, pentru doua obiecte de tip String, x si ye expresia x == y este adevarata doar daca x si y referi acelagi obiect de tip String, Astfel, dacd x gi y referd obiectediferite cu confinut idemtic, expresia x == yeste falsi. Acelasi rafionament este valabil si pentru ! Pentru a testa egalitatea a doui obiecte de tip String, se foloseste metoda equals. Expresia x.equals (y) este adevirati daci girurile de caractere referite de x gi de y sunt idemtice. ‘Ca exemplu si considerdim urmitoarele suri: | String x = Tabs 2String y= "ab": sString z= ys In aceasti stati, expresia x=y va fi falsi pentru cd x siy sont refernge cate dou obicet dierte (chiar daci se fntimpll ca acestea sh aibe acelagi conginut, si anume "ab", in timp ce expresia y == 2 va fi adevdratipentra coy gi 2 sunt refering cite acelai obiect. Pent a compara cele doud ira de caractorereferite de x si. se Tolosese metoda equals (). in concluzie, x,equals (y) vaio expresie adeviath Un test mai general poate fi realizat cu metoda compareTo (). Uiilzand expresia x..compareTo (y), se compari dous obiecte de tip String, x gi y. Valoatearetumata este un numir negativ, zero sau un num port doc teste mai mic, egal respectiv mai mare dec y din punct de vedere al ordi lexicograice. CComparareastingurlor poate fi realizata si ev ajutorel unei alte metode, umita conpareToIgnoreCase(). Accasté metoda are acelasicomporta- ment cu compareTo(), doar cd metoda compareToIgnoreCase() mi face distncie inte lterele mii s iterele marae alfabetw De exemplo, i: \ string a1 = cab": String #2 = “abod": fn acest az, expresia 81. compareTo (32) vafi fale, pentru cl "A" este difert de "a", in timp ce expresia 81. conpareToIgnozeCase (52) vafi adevarati pent ck metoda compareToIgnoreCase nu face diferens inte 4 5.3, SIRURI DE CARACTERE (STRINGUR literele mari si cele mici. Altfel spus, din punctul de vedere al metodei com- pareToIgnoreCase, "A" este egal cu "a". Este evident ci metoda com pareToIgnoreCase nu are sens si fie folositi pe giruri de caractere care nu ‘conjin litere, ain exemplulurmitor $1. compareToIgnoreCase ("123") 3.3.4 Alte metode pentru stringuri Lungimea unui obiect de tip String (un sir vid are lungimea 0) poate fi objinut cu metoda Length). Deoarece Length () este o metod’, In ‘momentul apelului parantezele sunt necesare [Existi dou metode pentru a accesa caracterele din interiorul unui String. Metoda charAt retumeazs caracterul aflat la pozijia specificatt (primul car- acter este pe pozijia 0). Metoda substring returneazs o referinja citre un String nou consiruit. Metoda are ca parametri pozitia de inceput si pozijia primului caracterneinclus. Tati un exemplu de folosire a acestor metode: String mesa} = "Hello": jat_TungimeMesa} = mesaj length (): Ulungimea este § char At (1): Weh este "e Ueub este “tt LLimbajul Java oferi o paleti impresionant de metode pentru manipularea sirurilor de caractere. Pe ling’ cele prezentate anterior, metode des utilizate sunt de asemenea: * concat () Descriere: metoda concat. adauga la sfirgitul unui sir de caractere un alt sir de caractere. Deoarece un obiect de tip String nu este modificabil (mutabiD), prin concatenare se va crea un nou obiect, ce va fi referit de variabila referingi $1. Fostul obiect referit de s1 va fl supus colectiri de ‘gunoaie, in situafia In care nici o alté variabil& mu fl refer’, Antet: String concat (String str) Exemplu: sSteing sl = tats ssl.concat ("b"): //s1 devine "ab" * endswith() Descriere: verifca dact sirul de caractere are ca sufix un alt sir de carac- tere, 15 {3 SIRURI DE CARACTERE (STRINGUR) Antet: boolean endsWith(String sufix) Exempla: String sl = “abede"s » System out printin (st -endsWith (*de" ))s St va afisa true, pentru ca sirul de caractere “abede” se tt termina cu siral de caractere "de" te # equaistgnorecase() Deseriere: verified dact dou sinus sunt egale, fri a face diferena itre literele mari gi cele miei ale alfabetului Aniet: boolean equalsignoreCase (String altstring) Exempla: String sl = “ABe* 2 System out. priatin (s1 .equalstgnoreCase ("abe"): crete eek es etl ieerteieceecahiar ta literete mic’ sf cele marl ole alfabetelul te # getBytes() Deseriere: converteste stringul intr-un sir de bytes(octeti), astfel incat fiecirui caracter din sir fi va corespunde un intreg de tip by te, reprezen- ‘nd primul byte din codul Unicode al caracterului respectiv’ Antet: byte [] getBytes() Exemplu: byte) b1 eas 14 sirul 61 va contine codurite Unicode ate caracteretor 4 4 ce formeaza sirul "abed", adica 97, 98, 99, 100 bed". gerBytes Qs “Ta eae, proces este ceva mal complex: metodn get ytee) va transforma coal Uni ‘ode l er caracter din (av nd ote) in codl pe I octet specifi platformel pe care ular rmajina vial 6 5.3, SIRURI DE CARACTERE (STRINGUR © indexof() Descriere: retuneazsi pozijia Ia care se afl prima aparitic a unui sub- sir intraun gir. Dac subsirul nu se regiseste in girul respectiv, metoda retureazit valoarea -1 Antet: int indexof (String str) Exemplu: String st pString $2 pString $3 System. out. printin(s1 -indexOf(s2)) ti) va afiza 9 (indicele din sl la care incepe subsirul 52) System. out. printia(s indexO#(s3)): SU) va afisa—T(siral s1 me contine subsirul 23) ul Java este orientat pe obiecte*; © last indexof () Descriere: retumneazi pozifia la care se aff ultima aparitie a unui subsir {inten sir. Dacd subsirul nu se afl in sirul respectiv, metoda returneaza valoarea-1 Antet: int lastIndexOf (String str) Exemplu: String 1 = "Bl invata Java pentru ca Java ¢ OOP pString #2 = “lavas 1 System out. printla (st lastIndexOf (s2)): 74 64 va aflsa 25 (indicete ta care incepe ultima aparitie + ta subsiratué s2 in sirut #1) * replace() Deseriere: inlocuieste aparifile unui caracter' run sireu un alt caracter si retumeaziinoul sir astfel format. Dacd respectivul caracter nu apare in sit, atunci noul sir va fila fel cu ce initial ‘Amtet: String replace (char carVechi, char carNou) Exemplu: + String st :String s2 = sl-replace('a’, 1/1 32 va avea valoarea *Jivi n {3 SIRURI DE CARACTERE (STRINGUR) © startewith() Desctiere: verifici daci un sir de caractere are ca prefix un alt sir de ccaractere, Antet: boolean startsWith (String prefix) Exempla: String st = “abed": 2 System out. printla(s1. startsWith ("abe"): ie 14 va afisa true pentru ca atringal si incepe ft ew sirul de caractere "abe" # toLowerCase() Descriere: converteste toate literele mari din string in litere mici. Antet: String toLowerCase() Exemplu: sString st = *ABOUE" iString #2 = s1.toLowerCase (): 31/32 va fi egal eu “abcde” * toupperCase() Deseriere: este opusa metodei toLowerCase. Converteste toate lterele smici in litere mari Antet: String toUpperCase() Exempla: y String s1 = ‘abCaB*; pSteing #2 = sl toUpperCase(): 31182 va fi egal eu "ABDCE™ etrim(y Descriere: elimina spapile de la inceputul si sférsitul unui sirde caractere. Ante: String trim() Exemplu: sString sl = 7 dave pel = sltrimQ: Dist va fi egal cu "Java" 8 4. SURI 3.3.5 Conversia de la string la tipurile primitive si invers Metoda toString) poate fi utilizati pentru a converti orice tip primi- tiv la String. De exemplu, toString (45) retumeazi o refering citre sirul nou construit “45”, Majoritatea obiectelor furnizeazi o implementare a metodei toString(). De fapt, atunci cand operatorul + are un operand de tip String, operandul care nu este de tip String este automat convert la String folosind metoda toString (). Pentru tipurile de date numerice, ‘exist o varianti a metodei toString () care permite precizarea unei anumite baze. Astfel, instrucjiunea: System out. printia (Integer toString (33, 2): are ca efecttipairea reprezentiii in baza 2 a numarului SS. Pentru a converti un String la un int exists posibilitatea de a folosi metoda Integer .parseTnt (). Aceasti metoda genereazi o exceptie daci ‘String-ul convertitnu confine o valoare intreaga. Pentru a objine un double Int arBlemente 0; //numaral de elemente citite mp String 8: “sir in care se citeste cote 0 Linke > System. out. printin("Introduceti steinguri:*): 4. SURI try i Meat timp linia este diferita de “end” while (1"end”-equalsignoreCase(s = in-eeadLine ())) t it (arElemente fi Maubleaza dimensiunea siralui “wmplus™ clemente = resize (clemente, lemente length « 2): 1 clemente [arElemente ++] ) clemente. length ) ceateh (Exception ©) t ) System out. printia("Citire incheiat return resize(elemente. arElemente ): Virunchiaza sirul la mumaral de elemente citite 1 Jes Afiseaza sirul de stringurl eltit. of public static void printSingleDimensional Ar t System. out. printin("Blementele citite sunt: for (int i #0: 1 < array. length; 14) ‘System out. printin array [1]): y (String [] array) 1 Jes Redimensioneaza sirul, of Public static String (| resize(String (] sir, int dimensivneNows ) t Int clementeDeCopiat = Math.min(sir length , dimensiuneNous ); String] sirNow = new String [dimensivneNows |: for (int i = 0; i < elementeDeCopiat; ++i) t ) return sirNou: 1 sirNou Li sirlils fee Transforma String] in charE]E. of public statte char []{] stringsToChars (String [] etay ) ( char J[] characters = new char{ array length J[51: for (int i= 0; i < array.lengths 14) 85 4 SUR sot 2 characters {i} = new char [array [i]. length ()15 . array [i]. getChars (0, characters [i J.lengih, characters{i], 0); Hoy “return characters: ) fee Afiseaza 0 matrice de caractere. +/ % public: static. veld printMultiDimensionalArray ( a char [][] characters) a 4» System.out. printin("Elemente sub forma de caractere:"): for (int i = 0: i < characters tengths 144) » | for (int j = 0; j < characters {i J-length; j+4) e System. out. print (characters (i J() 1) > System out. printia Q: my my a) 3.4.3 Siruri cu mai multe dimensiuni {n anumite situa trebuie s& stocim datele in siruri cu mai multe dimen- siuni, Cel mai des folosite sunt matricele, adic& sirurile cu doud dimer Alocarea de memorie pentru siruri cu mai multe dimensiuni se realizeaza pre- cizand numarul de elemente pentru fiecare indice, iar indicierea se face plasénd fiecare indice intre paranteze pitrate, Ca un exemplu, declaraia: ime (JU x = mew tne (2113) Adefineste matricea x, in care primul indice poate flO sau 1, iar al doilea poate lua valori de la 0 1a 2. Listing 3.2 ofera un exemplu simplu de utilizare a unei matrici. Dupa cum se poate observa la linia 10, sinul de stringuri ce a fost citit de la tastatura este transformat intr-o matrice de caractere (cAte un gir de caractere pentru fiecare string in parte). Metoda pr intMultiDimensionalArray prezinta modul de parcurgere a elementelor matricei objinute. 3.4.4 Argumente in linie de comanda Parametri transmisi in linie de comand sunt disponibili in cadrul unei apli- cafi, prin examinarea paramettilor functiei main). Sirul de stringuri numit 86 4. SURI args din funcjia main confine parametti transmisi programului Java in linia dde comand’, De exemplu, dack avem un program numit Suma. java pe care il executim cu comanda: java Suma 23 atunci parametrul args (0) va fio referin{i cdtre stringul "2, iar parametrul args([1] vafioreferinjicitre "3". Astfel, programul urmitor implementeazii © comandi de adunare a numerelortrimise ca argument sa argumentelor in line de comand Mafiseara sma parametrite 1 public static void. main( St + Tae Cares-tenes == 0) + | system out. printin ("Nu existe argumente"): so double soma = 0: wh for (int i = 0; 1 < args. length; #44) "sama + Double. parseDouble(aresti I): 4 e 1 S2sem out pentin Sama argumenteor: * + sums) i) Rezumat Capitola de fata prezentat tpurile refering. © referin este 0 variabilé care stocheaza adresa de memori unde se aff un obiect saa refering special niu, Refernfle pot indica doar obicete, ng variaile de tpar primitive. Orice obict poate fi refert prin na sau mai multe varibile refering. Deoarece in Java exist doar opt tipur primitive, aproape tol se traduce n obiecte si clase. Dinte obict, stringurle au un tratament mai special, pent ‘se pot folsi pentn concstenareoperstoi + si +=. in rest, stringurile sunt lal ca orice alt ip refering, Pent a testa dacd dou stringur sunt egale cast confinut, se foloseyte metoda equals 7 4 SUR rurile reprezinté o colecie de elomente de acelasi tip. Este important si rejinem foptul cd indicele de numerotae a elementelor din gir pormeste itot- deauna de a0. incadrul captoluui care urmeaza vom prezenta modul in care putem defini no tipuri de date in fava, flosind noiunea de clase. Nofiuni fundamentale apelare prin referin{&: in majoritatea limbajelor de programare, aceasta {inseam ef parameteul formal repreznta o refering cite parametrl ata ‘Aces fect este ains fn mod natural in Javan moment i care se utilzenzi Apel prin valoare pent tipur refering argument in linie de comand: argumentetransmise la execufa unui pro- gram lava i care sunt prelate in fonefiamain () colectarea de gunoaie: cliercarea automata din memorie a obicctelor care 1 mai sunt referite construire pentru obicte, se realizea prin intermediol cuvintlui cheie equals: metodi prin care se poste compara daci valoriestocate de dout obiecte sunt egale ‘Length (atribut): folost penta a determina dimensiunea unui se Length (metoda):folosii penta determina lingimea unui obiet de tip string obieet: oentitate de tip neprimii nei: flosit pentru a consrui noi obiecte 11011: refering special prin care se specific faptl c& nu se face referire Ia ici un obiect. NullPointerExcept Lon: tip de except generat de incercarea de @ accesa un atrbut sto metodi pe o refering nul pointer: casi referinja, pointeral congine adresa I cae se afl un obiect Spre deosebire de refernf, pinterii necesito dereferenjereexplicité pentrz 4 putea manipula obiectul indicat. in Fava nu exist pointer referinf: variaili care stocheazi adres Ia care se afl un obiee, 5 prin intermedia cireia poate fi manipulat obieetal care este refer fir: refine ocolecie de obiecte de acelasi tip Erori freevente 1, Pentru tipuri referinj& operatoru ccopiazi doar adrese. nu copiaza valorile obiectelor, El 88 4. SURI 2. Pentru tipuri refering (inclusiv stringuri)trebuie folositi metoda equals in loc de == pentru a testa dacd obiectele referite sunt egale ca si conginut. 3. Alocarea cu un element mai putin decat trebuie pentru giruri (indexarea incepe de la 01). 4. Tipurile referinta sunt implicit inijializate cu nu11, Niciun obiect nu este cconstruit fird apelul lui new. O excepfie Nul1PointerException Indic faptul c& afi uitat si alocayi memorie pentru un obiect. 5. fn Java siruile sunt indexate fa O 1a N ~ 1, unde W este dimensiones siralui Totugi Java verfcdvalonrea indicilor, i accesu nafaralimitelor este detectat fn timpul execu 6. Sirurile bidimensionale sunt indexate prin & (4 (3) sit AL, ] ean Pascal 7. Folosiji"" $i nu ** pentru a serie un spagiu sau alte caractere. Exercifi Pe seurt 1. Care sunt diferenfele majore inte tipurile primitive si tipuril referina? 2. Enumeraj $ operat care se pot aplica unui tip refering 3. Enumerati operatile de baz care pot fi efectuate pe stringuri Teorie 1. Dac x si y au valorile 5 respectiv 7, care este rezultatul urmitoarei afi System out. printin(x + °° + y): System out printin(x ©" " + yi fn practick 1. Creafi un sir de obiecte de tip String si asociaji un String fecirui ‘element din si. Afigaji apoi elementele girali cadral unui eielu Zor. 2. Scriofi o metoda care retmneaz true dacd stringul str este prefix Pentru stringul str2. Nu folosifi nici o metoda generala de ciutare pe stringuri in afaré de chart. 89 4 SUR 3, Scriefi un program care preia trei argumente de tip String din linia de ‘comandi si le afigeaza pe ecran. 90 4. Obiecte si clase CCovintcle sau limbgjul, aga cum sunt cle serge sau vorbite nu par i joace nici un ro n mecanismul indir mele, Obiectele care par Siserverasc drept element in indirea mea sunt anumite semne $1 imagini mai malt sau mai pojin clare eae pot fia mod voluntar reproduse sau combina. ‘iber Ensen fn acest capitol vom incepe si discutim despre programarea orientaté pe obiecte (object oriented programming - OOP) in Java. O component fun- damental programa orienate pe obiecte este specificare, implementarca fi folosirea obiectelor. In capitolul anterior am vizut deja citeva exemple de obiecte, cum arf stringurile, care fac parte din bibiotcilelimbajului Java, Am putt observa si faptl cd ficcareobiect este caraterzat deo amumit stare care poate fi modifica prin aplicarea operatoruoi pune (). in limbajel Java, starea fi funetonaltaten unui obiect se defines prin intermediul unei clase. Un obicet este de fat o insta a une clase fn cadralcaptoluelui de fas vom prezent: # Cum se foloseste in Java conceptul de clasa pentru a obfin« si ascunderea de informatii, concepte fundamentale ale OOP; + Cum se implementeaza o clasi Java; + Cum se pot grupa clasele in pachete pe baza funcionalitiii lor comune. 91 4.1 Ce este programarea orientata pe obiecte? Programareaorienati pe obiecte sa impus ca modelul dominant al anilor °90 s contin si domine gin deceniulcuren. in aceastsecjune vom prezenta modul fn care Java suport programarea orienta pe obiecte si vom mentiona catevadinire principle ei fundamentle In central programari orientate pe obiecte se afl nojumea de obiect. Obicc- tol este 0 variabilt complex definit de o structurd gi star. Fiecare obiect Aispune de operat prin intermediol cdrora i se poate manipula starea. Aga cum am vt deja, in limibajul Java se face distncie fre un obiec io vari bill de un tip primi, dar aceasta ese 0 specifctate a limbajului Java st mua rogramictoventate pe obiecte in general. Pe lingi opcrailecu un caracter seneral,aupra obictelor se mai pot realza gi alte opera * Crearea de noi obiecte, insofita eventual de inifializarea obiectelor; # Copierea si testarea egalitaiii; # Realizarea de operatii de intraresiesire cu obiecte. Obicctltrebuieprivt ca 0 nitate atomic pe care uilizatoral mu ar tebui si o disece. In mod normal, nu ne punem problema de a jongla cu biti din care este format un num reprezenat in vingul® mobil gar fi de-a dreptsl d= col si incercim si inerementim un asfel de mumir prin modificares direct & reprezentii sale interne. Principiul atomicitafii este cunoscut sub numele de ascunderea informari- «i, Uiiizatorul nu are acces direct la componente uni obiect sat I imple- mentarea sa, Acestea vor putea fi accesate doar prin intermediul metadelor care au fost famizate impreuni cu obieetl, Putem prvi ficare obit f- ind ambalt intro cutie pe care este scris "Nu deschidel Nu confine compo nentereparabile de ctr uilizator*.Inviga de zi eu zi, majoritatea celor care incearc si repare componente eu aceastiinsciptiesfirgese prin a face mai rl ru deci bine. Din acest punet de vedere, programarea iit limea reali GGruparea datelor sa operailor asupraacestor date in cela integ (agregat). avand grit si ascundem detaile de implementare ale agregatul, este cunos- cut sub numele de ineapsulare. Agadar, datele sunt ascunse, iar accesul lor se realizea prin intermedivl operailorincapsulate impreund cu ele, mime metode ‘Unul dnte prineipalele scopur ale programisi orientate pe obiecte este 1e- utlizarea coduli. La fel cum inginesirefolosese din nou si din now aceleasi components in proicctarca de componente electronic, programatori ar rebui 2 4 refoloseasci obiectele in loc si le reimplementeze, Exist doua situa dis- tincte legate de reutilizarea codulu (refolosirea obiectelor) 1. Situajia in care avem deja la dispo ‘act comportamentul pe care il dorim, Refolosirea obiectului nu pune in acest caz nici un fel de probleme; ituafia fn care dorim si folosim un obiect care deja exist, dar care, desi fare un comportament foarte similar cu ceea ce vrem, nu corespunde ex- act cu necesitifile noastre, Aici este de fapt adevarata provocare: obiectul existent va trebui extins pentru a fi adaptat la comportamental dorit. Ast- fel se economiseste timp de dezvoltare, deoarece adeseori este mult mai ugor si se adapteze un obiect deja existent (a carui functionalitate este ‘asemiinitoare cu cea a obiectului de eare avem nevoie) decat si se reserie totul dela zero, Limbajele de programare orientate pe obiecte furnizeaz8 mai multe mecanisme entra a faciitareuilizarea codulul. Unul dintre mecanisme este folsirea co- dului generic. Dact implementarea este identic, gi diferi doar tipul de baz al obiectuui, nu este necesar si rescriem complet codul: vom serie tn schimb un cod generic care funcfioneazi pentru orice tip. De exemplu,algoritmul de sortare al unui gir de obieete nu depinde de obiectele care sunt sorate, deci se poate implementa un algoritm generic de sortare Mostenirea este un alt mecanism care permite extinderea functionaliti unui object. Cu alte cuvinte,putem crea noi tipuri de date care si extinds (sau si restrcjioneze) propritaile ipului de date original Unt prineipa important al programri orientate pe obiecte este polimor- fismul, Un tip refering polimorfic poate si refere obiecte de mai multe tipuri. ‘Atunci cind se apeleazi o metodd a tipului polimorfic, se va selecta automat tmetoda eare corespunde tpului referit in acel moment (vom descre in deta ald mogteniteacAt si polimorfismul fa capitoll urmator) Un obiectin Java este o instanfi a unei clase. O clas este similard cu un tip record din Pascal sau cu o strcturl din C, doar c& exist dou imbundtiri ma- jore. in primul rind, membaiiclasei pot fait func ft si date, numite in acest context metode, respect atribue, in al doilea rind, domeniul de vzibititate al acestor membri poate fi resticffonat. Deoarece metodele care manipuleazi starea obiectului sunt membri ai clase, ele sunt accesate prin intermedi! o- peratorului punct, la fel ca gi atibuele. in terminologia programri orientate pe obiecte, atunei cénd apelam o metodt a obiectului spunem 8 “wimitem un ‘mesaj" obiectulu 93 42 ovexewntwsimno 4.2. Un exemplu simplu Stine amintim cA, atuncicind proiectimo clas, este important st ascundem etal inteme fa de uilizatoru clase, Casa poste si igi defineasd funcfio- nalitates prin intermediul merodelor. Unele dinte aceste metode vor descr ‘cum se ereeaz gis iiilizeario intan a clasei, cum se reaizenzatestcle de egalitate si cum se descrie starea classi, Clelalte metode sunt specifice structuri paniculare pe care are clasa,Ideea este c@ utilizatorl na tebuie i aiba dreptul de a modifica direct starea obiectuui, ciel va tebui s8 foloseasca metodeleclasei pent a realiza acest liens. Aceast idee poate fi impusé prin ascunderea anumitor membri faté de uilizator. Pentru a realiza accasa, vom preciza.a acesti membi si fe stoaf in sects private. Compilatonl va aveagrijca membri din seefiunea private sf fe inaccesbili utlizatoulas acelui obiect. in general, toate atrbutele unui obiect ar trebui si fe declarate private Programul din Listing 4.1 prezint& modul de definite al une clase care mo- deleart un cere. Defiirea clasei const in dou pani: public si private. Secjianea public reprezintt porjonea care este viibilt pent wtilizatoral obiectului. Deoarece datele sunt ascunse fa de utilizar, seciunea public va contine fn mod normal numai metode si constantc. fn exempll nos avem dovit metode, una pentre a serie si una penta a citi raza obiectlor de tip Circle, Celelalte dvi metode calelesza aria respect hingimea obiecti- lui de ip Circle. Sectiunea private confine datcle; acestea sunt inv pentr utilizatorslobicetului, Atributul radius poste f accesat done prin in- termedial metodelorpublice set Radius () si get Radius 0) le Listing 4.1: Definirea clasei Circle i Clase simple Java care modeleaza un Cere Uvaloarea razei mu pos Wdireet de private dou! modificata Nl fas Modifica raza cerewtuis/ public veld setRadius (double +) of radius oo 6 fos Metoda pir @ obtine raza cercului.+/ 462, UNEXEMPLU SIMPLU © public 4 af SS return radius: = fee Metoda pir caleulul ariei cereului.e/ public double area) at Me eturn Math. PL + radivs + radius; He getRadivs () tr cateetal tenginil.+/ Te tength Programul din Listing 4.2 prezinta modul de foosire al unui obiect de tip Circle. Deorece setRadius(), getRadius(},area() si length() sunt membri ai clasei, ei sunt accesati folosind operatorul pune. Atributul radius ar fi putut si el si fie accesat folosind operatorul punct, daci nu ar fi fost declarat de tip private. Accesarea lui radius din linia 15 ar fi fost legals dac& nu era comentaté folosind //. ‘S8 rezumim terminologia invajatd. © clasti confine membri care pot fi ‘arribute (campuri, date) sau metode (functii). Metodele pot actiona asupra atributelor si pot apela alte metode, Moditficatorul de vizibilitate public face ‘ca membrul respectiv si fie accesibil oricu prin intermediul operatorului punct. Modificatorul de vizibilitate private face ca membrul respectiv si fie acce- sibil doar metodelor clasei, Daci nu se pune nici un modificator de vizibilitate, atunci accesul la membru este de tip friendly, despre care vom vorbi in paragra- ful 4.44, Mai exist si un al patrulea modificator, numit protected pe care il vom prezenta in capitolul urmator. Listing 4.2: Testarea clasei Circle \Welasa simpla de testare @ clasel Circle + public class TestCircle public statte void main(String () i {© GCirele circle = new Circle (): Bs) circle. setRadius (1 System out. printla System out. printia System out. peintia("Lungime cle. getRadius ()); ele area ()) + circle length ()): 5 Hurmaroarea Tinie ar genera o 95 4 Heroare de compitare | Helrete. radius = 20, ee eat 4.3. Metode uzuale Metodele unei clase se pot grupa in douit categori # metode cla ‘uzuale, care se regisese in (aproape) toate clasele; # metode care definese comportamente specifice unei anumite clase. {In aceasta sectiune vom prezenta prima categorie de metode: constructor, modificatorii, accesorii, toString () si equals () « 4.3.1 Constructori ‘Asa cum am mentionat deja, una dintre proprictaile fundamentale ale obi- ectclor este acestea pot i defnite si, eventual, iniializate. In limbajul Java, tnetoda care controleazi mol in care un obieet este creat gi infinlizat este consiructorul. Deoarece Java permite supraineirearea metodelor, 0 casi poate $i defneasei mai mult constructor act la definire clase nu se furnizea nici un constrictor, cum este cal clasci Circle din Listing 4.1, compiatorulereesza automat un constric- tor implicit care iniilizeazd fecare membru ex valorileimplicite. Accasta {nseamni ci stributele de tipuri primitive sunt iniializate cu 0 (cele boolean cu £a11se) iar atributele de tp referin sunt iniializate cu m1. Aste, in eazal ost, arbutul racitss vaavea implicit valoarea 0. ent a furniza un constructor, vom serie o metodi care are acelagi nme cu clasa care nu returneazi nimi. In Listing 4.3 aver doi constructor: unul incepe la linia 7, iar celia Ia linia 15. Folosind acesti doi constructor vom putea crea obiecte de tip Date in urmitoarete modi Dite di = new Date(s Date 42 = new Date(1S, 3, 20005 De remarcat faptulc¥ odati ce afi definit un constructor pentru o clas’, com- pilatorul nu mai genereaza constructorul implicit id parametsi, Daca veji avea nevoie de un constructor fri parametri, va trebui acum si il scriefi singuri. De exemplu, constructor din linia 7 trebuie definit obligatoriu pentru a putea crea un obiect de tipul celui referit de cate di. 96. 43, MeTODE UZUALE Listing 4.3: O clas Date minimal care ilustreazs constructorii si metodele equals () si toString () Telasa Java simpla penire stocarea weal > Haw se face validarea datelor & public class Date so 6 © Heonstructor fara parametri : lie Date) 7 ot ty ets month = 1 " year = 2000; ey me Meomstrnctor on tret parametri public Date(int theDay, int theMonth, int theYear) sf ay = theDay: month = theMonth year = theYear: » oy 2B Htest de egalirare BD Hintoarce tre daca Oblectul x este egal cu objectul curent ” blic boolean equals (Object x) » ft Ee if (1x Instanceot Date) return f = Date date = (Date) x: return date. day == day && date.month == month 5 ‘Kk date. year == year my ™ — Heonversie ta String Ss public String toString () » ” return day 4 °/* + month 4 °/* 4 year 5 wy = Hatribure & private tnt day: private imt month: fo private int years a 7 43, METODE UZUALE 43.2 Modificatori gi accesori Atributele sunt declarate de obicei ca find private. Aceasta inseam’ ci cle nu vor putea fi direct accesate de citre rutinele care nu aparfin clase. Exist ‘otusi multe situapi in care dorim si examinim sau chiar si modificim valoarea unui atribut posibilitae este aceea de a declara atributele ca fiind public. Aceasta ru este o solutie elegant, deoarece incalea principiul ascunderii informatie utem insi scrie metode care si examineze sau si modifice valoarea fiecarui cmp. O metodi care citeste, dar nu modifica starea unui obiect este numiti accesor. O metodi care modifica starea unui obiect este numita modificaror (engl, mutator) ‘Cazuri particulare de accesori si modificatori sunt cele care acjioneazsi asu- pra unui singur cimp. Accesorii de acest tip au un nume care incepe de obicei cu get, cum ar fi getRadius (), iar modificatorii au un nume care incepe de regulicu set, cum ar fi setRadius (). Aceste metode sunt atat de des folosite in Java, Incdt au si denumiri consacrate in limbajul uzual al programa- torilor Java: getteri, respectiv sesteri (a nu se confunda cu rasa de patrupede ‘care poarté acelasi nume). ‘Avantajul folosirii unui modificator (sau a unui setter) este ci acesta poate verifica daci starea obiectului este corectd, Astfel, un setter care modific’ atributul day al unui object de tip Date poate verifica corectitudinea datei ‘care rezult. 433. Afigare si tostring() fn genera, afigarea stiri unui obiect se face wilizand metoda print () din clasa System. out. Pentn a putea face acest her trebuie ca obiectil eae se doreste af afigat si contin o metodi cu numele de toString (). Aceasti metodt intoaree un Sting (eprezentindstarea obiectwhui care poate aig Cauun exemplu in Listing 43 am prezenta o implementa rudiment unei metode toString () pentns elasa Date in linile 35-38, Definirea acestet metode permite si afigim un obiect di de ip Date folosind insrutiunea system. out .print (di). Practic, compilatorl Java nu face altceva decit si invoce automat £oSteing () penta flecare obiect care se afigeaza. Ast- fel system.out .print (dl) este tradusi de cate compilator in instuci- unea System.out .print (41.tosteing()). Aceasti simplé facilitate las8impresiaprogramatorlorneavizaji cd metoda pent () “sie” si afigeze obiecte Java. In realitate, metoda print () nu ste dec si afgezestringurt ‘Compilatorl Java este inst sufcient de intligent pens a transforma obietcle 98 in stringuri, prin apelul metodei toString () (de altfe, tot compilatorul este cel care converteste la afigare gi tipurile primitive la String, atunci cind este canul) 4.3.4 Metoda equals () Metoda equals este folositi pentru a testa dact doud referinie indici obi- ccte care au aceeasi valoare (stare). Antetul acestei metode este intotdeauna public bi san equals (Object rhs) Aji emareat probabil nedumeriifaptl ck parametrul trims metodei este de tip Object si mu de tip Date, cum ar fi fost de asteptat. Rajunea acest lent so prezentim in capitolal umtor. fn general, metoda eqqva_s pentnt o clas x este implementa in aa fl inet sf retumeze true doar dack rhs (abreviere pentru “ight hand side”, adicd operandul din partea dreaptia expre- sie) este 0 instang a lui x s, fm plus, dupa conversa la X toate atibuele lat ‘hs suntegale cu atibuteleobiectululi(atrbutele de tip primi trebue si fie egale via ==, iar atributele de ip referingStebuie si fie egate via equals ()) Un exemplu de implementare a lui equals este dat in Listing 4.3 pent: clasa Date in linile 25-32. 4.3.5 Metode statice [Existi anumite cuvinte cheie ale limbajului Java care specificd proprietii speciale pentru unele atribute sau metode. Un astfel de cuvant cheie este sta~ tic. Auibutele si metodele declarate st at ic tntr-o clas, sunt aceleasi pentru toate obiectele, adicd pentru toate variabilele de tipul acelei clase. Fiind identice pentru toate obiectele unei clase, metodele statice pot fi accesate far’ si fle nevoie de 0 instanfiere a clasei respective (adica de o variabila de clasa respec- tiv). Metodele statice pot utiliza variabile statce declarate tn interiorul clase. Cel mai cunoscut exemplu de metodi statickeste main). Alte exemplede metode statice pot fi gisite in clasele String, Integer si Math. Exemple de astfel de metode sunt String. valueof (), Integer .parsernt (), Math.sin() siMath.max (). Accesul la metodele statice respect aceleasi reguli de vizibilitate ca $i metodele normale. 4.3.6 Atribute statice Atributele statice sunt folosite tn situafia in care avem variabile care trebuie partajate de c¥tre toate instanjele unei clase. De obicei atributele statice sunt 99 43, METODE UZUALE constante simbolice, dar acest lucru nu este obligatoriu. Atunci cind un atribut al unei clase este declarat de tip static, doar o singur’ instangi a acelei variable va fi creat, Ea nu face parte din nici o instanfa a clasei, Ea se comporti ca tun fel de vatiabild global unics, vizibilé in cadrul clasei. Cu alte cuvinte, dacd avem declarayia «public Ht 5 private Int x: 1 private static Int y: s 2 Exempla fiecare obiect de tip ExempLu va avea propriul atribut x, dar va fi doar un singue y partajat de toate instanjele clasei Exemp1u, (© folosire frecventé pentru cmpurile statice o reprezinté constantele, De cexemplu, clasa Integer definesteatributul MAX_VALUE astfel public final statie int MAX.VALUE = 2147483687; Analog se defineste si constanta PZ din clasa Math pe care am folosit © in clasa Circle, Modificatorsl final indica faptu cd identiicatoral care turmeazi esto constants, Dac8aceast constant nu arf fostun arbut stat ic, stuneifccare instal a classi Integer ar fi avut un atribut eu numele de MAX_VALUE, irosind astflinutil spa in memoric. ‘Aste, vom avea o singuravarabila cu numele de MAX_VALUE, Constante poate fi accesati de orcare dintre metodcle clasei Integer prin identifcatorsl MAX_VALUB, Ea va putea fi folositi side eitroun obiectde tip Integer mumit > prin sintaxa x,MAX_VALUE, ea orice altedmp. Acesthuer este permis doar pentru ei MAX_VALUB este pobl ic. fnsfirit,MAX_VALUE poate folosit prin intermedia numeluiclasei ca Integer .€Ax_VALUE (lot pentru cd este ub1.c). Aceast ullims folosire nu arf fost permis pent un efmp care ni sxe static Chiat si fra modificatoral £:na, atributlestatce sunt foarte folositoae Si presupinem ci vrem si rejinem nunnul de obiecte de tip Circle care au fost constute. Pentru aceasta avem nevoie de o variabili stata. fn clasa Cixede vom face dectaajia: private static int numarlastante = 0: ‘Vom putea apoi incrementa numairul de instanje in constructor. Dac acest ‘cimp nu arf fost de tip stat ic am avea un comportament incorect, deoarece fiecare object de tip Circle ar fi avut propriul atribut numarInetante care ‘ar fi fost incrementat de Ia 0 Ia 1 Remarcaji faptul c8, deoarece un atribut de tip static nu necesita un obiect care s& il controleze, fiind partajat de care toate instanjele clasei, el poate fi 100 folosit de catre o metodi static’ (daci regulile de vizbilitate permit acest lucru), Aributele nestatice ale unei clase vor putea fi folosite de cate 0 metodi staticd, doar daca se furnizeaza si un obiect care si le controleze. 4.3.7. Metoda main() ‘Atunei end este invocat, interpretonul java cauti metoda main () din clasa care i se di ca parametru. Astel, in situfia in care aplicafia noastri este formati din mai multe clase, putem serie c@te 0 metod main () pentru flecare clasi, Acest lucru ne permite si testm funcfionalitatea de bazi a claselor in viduale. Trebuie si avem totugi in vedere faptul c¥ plasarea functiei main () {in cadrul clasei ne confer mai multi vizibilitate decit ne-ar fi permis prin uti- lizarea clasei din alt loc. Astfel, apeluri ale metodelor private pot fi Facute {in test, dar ele vor esua cdnd vor fi utiliza in afara clase 44 Pachete Pachetele sunt folosite pentru a organiza clasele similare. Fiecare pachet consti dinu-o muljime de clase. Clasele care sunt in acelagi pachet au restrietii de vizibilitate mai slabe fntre ele decat clasele din pachete diferte Java oferiio serie de pachete predefinte, prinre care java. io, java. awt, java.lang, java.util, java.applet ete. Pachetul java.lang in- clude, printre altele, clasele Integer, Math, String si System, Clase ‘mai cunoscute din java.util sunt Date, Random, StringTokenizer, Pachetul java. Lo cuprinde diverse clase pentru stream-uri, pe care le vom prezenta in capitolul 7. De asemenea, pentru o prezentare mai amanunftd a pachetelor predefinite, vi recomandim si consultaji anexa C. Pe linga infor- ‘mati detaliate despre aceste pachete si despre modalitatea de a vi crea propriile dumneavoastra pachete, anexa C prezinti gi nofiunea de arhiva jar, foarte utili, ‘cadnalaplicafilor de dimensiuni mai mari (O clasi oarecare C dintr-un pachet P este desemnati prin P.C. De exemplu, putem declara un obiect de tip Date care si congind data si ora curenth astfel: java. util Date today = new java. util Date(s ‘Observasi ed prin specificarea numelui pachetului din care face parte clasa, evitim conflictele care pot fi generate de clase cu acelagi nume din pachete diferte! "De exempl, a casa Dace Sef anterior in sectonen 43 101 44 PACHETE 4.4.1 Direetiva import Utlizarea permanent a numelui pachetului din care fac parte clasele poate fi uncori deosebit de anevoioasd, Pentru a evita acest lucru se foloseste directiva import: Import NumePachet .NumeClasa Import NomePachet +; acd recurgem la prima forma a directivei import, vom putea folo numirea NumeC1asa ca o prescurtare pentru numele clasei cu calificare com- pleti. Dac folosim cea de-a doua forma, toate clasele din pachet vor putea fi abreviate cu numele lor neprecedat de numele pachetuli De exemplu, realizind directivele import de mai jos: Import java.util Date: slmport java.io.+: putem si folosim: public statle double readDouble() » ¢ return Double. parseDouble(readString ()): my he public statte char readChar() » Ct % BufferedReader in = new BufferedReader new InputStreamReader (System in )) no ty 5 0 a return (ehar)in read (): an eaten (IOException ©) » « Wignore so fe return "\0"s eo public statle Int[] readintarray () » ¢ String s = readstring hn StringTokenizer st = new SteingTokenizer (3): b Unt {] & = mew Int[st-countTokeas ()] Se for (int i = 0; i < a.tength; +6) st » ali] = Integer. parselnt (st. nextToken (9): so so wy 4.4.4 Reguli de vizibilitate package-friendly x importants, In primal rind, dact Pachetele au céteva reguli de vizibili pentru un membru al unei clase nu se pi vibilitate (public, protected sau private), atunei membrul respectiv devine (package) friendly. Aceasta inseamnii ci acel cmp este vizibil doar pentru clasele din cadrul aceluiasi pachet. Aceasta este o vizibilitate mai pugin restrctivi decat private, dar mai restrictiva decdt public (care este vizibil si pentru membrii din alte clase, chiar si din pachete diferite). {nal doitea rand, doarclasele pub1ic din cadrul unui pachet pot fi folosite din afara pachetului. Acesta este motivul pentru care am pus intotdeauna modi- 105 ‘un modificator de vi 45, ALTE OPERATII CU OBIECTE SL CLASE ficatorul publ ic in faa unei clase. Clasele nu pot fi declarate private sau protected (cu o singura excepfie: clasele interioare, despre care vom vorbi in capitolul urmator), Accesul de tip friendly se extinde si pentru clase. Dac 6 clasa mu este declarati ca fiind de tip publ ic, atunei ea va putea fi accesata doar de clasele din cadrul aceluiasi pachet. ‘Toate elasele care nu fac parte din nici un pachet, dar sunt accesibile find puse intr-un director din CLASSPATH, sunt considerate automat ca ficnd parte din acelasi pachet implicit. Ca o consecin{a, accesul de tip friendly se aplic’ pentru toate aceste clase. Acesta este motivul pentru care vizibilitatea nu este afectati daci omitem si punem modificatorul public in clasele eare nu fac parte dintr-un pachet. Totusi, aceast modalitate de folosire a accesului friendly ru este recomandats, 4.4.5 Compilarea separati ‘Atunci cind o aplicajie consti din mai multe figiere sursi. java, fecare fsier tebuie compiatsepart. In mod normal, fecare clash este plasat intr-un fsier . java propru, Ca urmare a compilari vom objne o colectie de isi selage, Claselesursi pot fi compilate in orice ondine, Pentns a compila toate fgerele suri dint-an director printro singuré comands, pute flosi o extensie a comenzii javac, astel Javac *. java 4.5. Alte operatii cu obiecte si clase {in aceasti sectiune vom prezenta inci trei cuvinte cheie importante: this, instanceof si static. this are mai multe utiliziri in J tre ele le vom prezenta in aceasti secjiune. instanceof are si el mai multe utilize; il vom folosi aici pentru a ne asigura c¥ o conversie de tip se poate re- liza. $i cuvantul cheie stat ic are mai multe semnificati. Vom vorbi despre rmetode statice, atribute statice ¢ inifializatori static. a. Dou dine 4.5.1 Referinta this Cea mai cunoscutd utilizare pentru this este ca o refering’ la obiectul curent, Imaginafi-va c this va indicd in fiecare moment locul unde va aflai. O utilizare tipic’ pentru this este calificarea atributelor unei clase in cadrul 106 45. ALTE OPERATILCU OBIECTE Sl CLASE uunei metode a clasei care primeste parametri eu nume i butelor. De exemplu, in clasa Circle, din Lis setRadius astfel antic eu numele atri- 18 4.1, putem defini metoda Vas Modifica raza cercului, #/ Speblic veld. seiRadivs (double radios) u Mradius este parametrul Shae this radias tore atriburul clasei {thie radios “S"raaiae n fn seeventa de cod precedent, pentes a face distnetie intre parametal adie g aributul cu acelagi nme (care este “ascuns" de cite parametny) se foloseste sintaxa this . radius pentna a refer atibutl clase Un alt exemplu de folosire al hi thie este penta testa cd parametrul pe care o metodi il primeste nu este chiar obiectulcurent. Si presupunem, de ‘exempl, cd avem o clasé Account care are o metoda final Transfer () pentn a transera toa suma de bani dintran contin altul. Metoda ar putea seria ste: ‘public void finalTransfer(Account eecount) 5) dollars += account. dollars 1 account dollars = 0: seeventa de cod de mai jos: Account account Account accoust?: ‘account? = account! : Saccountl final Transfer account?) Deoarece transferim bani in cadrul aceluiasi cont, nu ar trebui si fie nici © modificare in cadrul contului. Totusi, ultima linie din final Transfer () are ca efect golirea contului debitor, ceea ce va face ca suma din account 2 si fie nul. O modalitate de a evita 0 astfel de situajie este folosirea unui test pentru pseudonime (referinje care indic& acelasi obiect): ‘public yold finalTransfer(Account eccount) af Udaca se incearca un transfer in acelasi cont ir (this == account) 107 45. ALTE OPERATII CU OBIECTE 1 CLASE + dollars += account. dollars account. dolla 4.5.2 Prescurtarea this pentru constructori “Mute clase dispun de mai mull constructri care au un comportament si- milar, Putem folosi this tm cadrul unui constrictor pentru a apela celal constructori ai clase, De exemplu, o alth posbilitate de a serie constructoru! fr parametri pentru clasa Date ese: \ pubite Date) 2 Hapeteasa constructorul Date(int, int, int) «this, 1, 2000): ‘Se pot realiza si exemple mai complicate, dar intotdeauna apelul lui this trebuie si fie prima instrucjiune din constructor, celelalte instrucfiuni fiind in continuarea acesteia, 4.5.3 Operatorul instanceof Operatorul instanceof realizeazi o testare de ti Reaultatul expresiei: timpul executiei exp Instanceot NumeClasa este true dacd exp este 0 instanjaa lui NumeC1 asa gi false in caz contrar, Daci exp este nu11, rezultatul este intotdeauna false. instanceof este folosit de obicei inainte de o conversie de tip, si adescori este folosit in legaturt cu referingele polimorfice pe care le vom prezenta in capitolul urmitor. 4.5.4 Inifializatori statici Atributcle statice sunt inijializate atunci cfnd clasa este sie, Uneori este inst nevoie de o initializare mai complex a acestor atribute. ‘Si presupunem de exemplu cl avem nevoie de un sir static care specific’ pentru fiecare numa intze 0 $i 100 daci este numa prim sau nu, O posibilitate ar fi si definim o metodi staticd si si cerem programatorului si apeleze acea metoda inainte de a folosi sirul altemativi mai elegant la aceasti solugie este folosirea inijalizatorului stati Instructiunile din cadrul initializatorului static sunt executate automat la Incircarea clasei in memorie (deci inainte de a fi creat prima instanga), ceea 108 45. ALTE OPERATILCU OBIECTE Sl CLASE ce ne asigura cf atributele statice sunt corectintializate Ia tilizarea clasei. Un ‘exemplu este prezentat in Listing 4.5, Aiciiniializatorul static se extinde de la linia 5 la linia 20, Injializatorul static trebuie si urmeze imediat dup membrul static, Listing 4.5: Clasa Prime, care foloseste 0 seevengi staticl de inifializare public class Prime 2) private statle boolean prime[] = new boolean [100]: static ‘ot > for (int i = 2: 1 < prime length; +43) : ¢ : prime(i} = 0 * for (int 5 " c & iwi Ee ( 5 prime(i] = false " break: “ ) a ) 1 = 4 2 Hrestul etaset Rezumat Acest capitol descrie nofiunile de obiect si clas, precum si elementele fun- damentale legate de acestea, cum ar fi atribute, metode, constructor, reguli de vizibilitate si pachete. Clasa este mecanismul prin care Java permite crearea de uri referinj&. Pachetele sunt folosite pentru a grupa clase cu comporta- ‘ment similar, Pentru o mai bund injelegere a pachetelor si a modului de operare ‘eu ele va invitim s& consultati anexa C. Tot acolo vefi alla ci toate clasele ‘care compun o aplicajie pot fi grupate intr-un singur fier, indiferent daci sunt “onganizate pe pachete sau nu. Rezultatul va fio arhivi jar. Capitolul urmator prezint& alte concepte importante ale programarii orien- tate pe obiecte: mostenirea, polimorfismul, programarea genericd. 09 45. ALTE OPERA CU OBIECTE SLCLASE Nofiuni fundamentale las: concept care grupeazs atribute $i metode care sunt aplicate instanjelor clase CLASSPATH: variabili sistem care specified directoarele gi figierele arhive {in care masina viruali JVM cauti clasele folosite de aplicaile Java, constructor: metodi speciali responsabili cu crearea si init instanje ale clase. constructor this: folosit pentru a apela un alt constructor din aceeasi clasi, friendly: tip de acces prin care clasele/metodele/atributele asociate nu sunt accesibile decat in interiors! pachetului din care fac parte. impor t: instrucjiune prin care se oferi o prescurtare pentru un nume com- plet de clas (numele complet include si pachetul din care provine clasa), ializator static: secvenfa din cadrul unei clase care permite inijializarea atributelor statice, obiect: instangi a unei clase, pachet: termen folosit pentru a organi similar, package: instrucjiune care indici faptul cl o clas este membri a unui pachet, Trebuie si preceadi definirea unei clase private: tip de acces prin care atributele/metodele sunt complet ascunse celorlalte clase, putnd fi utilizate doar in cadrul clasei din care fac parte. publ ic: tip de acces prin care atributele/metodele unei clase sunt vizibile in restul clasclor. referinfa this: referin(a citre obiectul curent. static: cuvint cheie prin care se precizeaza faptul c& o metoda sau un atribut sunt comune pentru toate instanjele clasei. Membrii statici nu necesito instanga pentnt a fi accesaj izarea de noi ccoleefi de clase cu comportament Erori frecvente 1. Membrii private mu pot fi accesafi din afara clasei. Rejinefi ci, im- plicit, membrii unei clase sunt friendly. Ei sunt vizibili doar in cadrul, pachetulu. 2, Folosiji public class in loc de class, cu excepfia situajei in care scriei o clasi ajutatoare de care nu vesi mai avea nevoie in afara pachetu- i, 10 45. ALTE OPERATILCU OBIECTE Sl CLASE 3. Parametrl formal al metodei equats tebuie st fie de tip Obsect. in car contra, desi program se va compila, in anumitesituai se va apela metoda equa: s implicit (care compara obiectlefolosind 4, Metodele statice nu pot accesa atributele nestatice far un obiect care $8 le controleze. 5. Deseori se uiti adiugarea " . +" atunci ednd se doreste importarea tuturor super (a: a ‘Metoda super poate fi utlizatd si pentru a apela constructori cu paramett De exemplu, daci avem o clasi de bazii care are un constructor cu doi parametti de tip int, atunci constructoral clasei derivate va avea in general forma: \pabllc Derived(int x, int y) 3 mperex, 90: 1 atte instreettunt 4 Metoda super () poate st apari doar in prima nie dinte-un constructor Daci nu se face un apel explicit al lui super (), compilatorl va realiza au tomatun apel al metodei super () fr parametr chiar la fnceputul construc- torului, Este important de remarcatc% apelul implicit este etre constructor! implicit (Fa8 parameti al casei de baz8. Dact acest constructor nu exist (si ni uitim cf el se genereazd automat doar dac8 nu exist ali constrictori), ‘objine eroate Ia compilare. De exemplu,clasa Base de mai jos defines un constrictor eu un parametri de tip int: public class Base t public Base(int x) ‘ System. out. printin("Base(int) called.") ; 1 1 Clasa Derived, extinde clasa Base, redefineste constructorul cu parametra de tip int gi defineste 0 metodima in () care creeaziiun obiect de tip Derived: public class Derived extends Base a public Derived ( int x ) i 5 System, out, printin ("Derived (int) called") + oo public statte vold main(String [] ares) i new Derived (2) 5 no " Aparent, nimic nu este in neregul cu aceste clase. Totusi, construirea obiee- lului Derived, presupune construirea in prealabil a obiectului Base, pe care acesta fl extinde. Cum constructorul din Derived nu confine un apel explicit, alconstructorului din Base, compilatoral va adiuga automat un apel eitre con- structorul implicit. Dar, surpizi! Acest constructor nu existi gi nici mu a fost ‘generat implicit, deci se va objine o eroare la compilare, fn care suntem anunfati cu parere de ru ci “nu a fost gisit constructorul Base ()". Corect este ca prima linie din constructorul clasei Der ived sti fie un apel citre constructorul cu parametru de tip int din clasa Base: public Derived ( int x ) a 2 super(x) 4 System. out. printin ("Derived (iat) ealled.*) ; sy La execujiaclasei Der ived se va afisa in consol: Base(int) called. Derived(int) called. 5.2.3 Redefinirea metodelor. Polimorfism Polimorfismul, a treitea concept fundamental al program orientate pe obiecte, altar de ineapsulae si mostnire, cteazA adeseor un animit prad de confuzie in randul programatorilor ncepétori, Vom rma in acest paragaf i clarfcim aceasta importanténofune, icra absolut necesar pentru o injelegere profunda a programa orientate pe obiect. CCapacitatea dea asuma diferte forme poarti numele de “polimorfism". Apa oferi un bun exemplu de polimorfism in lamea teal: apare sub forma solid (hea) chia, sau gazoasa (vapori de apa). fn Jaa, polimorismul inseamna co singura variabiléreferinj& poate fi folosté penta desemna mai multe obiecte - instanje ale unor clase similare! - in diferite momente ale executici Tyrael cae derivate direst su inst din sceag cls de baz 122 i program, Cand o referinja x este folosita pentru a invoca © metoda a unui obiect (de exemplu, x. met odatea ()), metoda precisa care va fi apelati. ‘depinde de obiectul pe care variabila referinjl il indica in acel moment. (© variabilé referinj& poate referi un obiect a carui clas este similar’ cu tipal variabilei referinja. De exemplu, si presupunem c& avem clasele Animal, Pisica, Soarece, Caine, definite ca mai jos: Listing 5.2: Exemplu de polimorfism public class Animal ‘ public String caracterist t 2) an a | a0 bile String caracteristica() Dpublic class Caine extends Animal af 5) public String caracte: a0 public class PolimorfismEx af lic static void main(String args (]) e ‘Animal a = new Soarece (); ™ System-out-printin("Caracteristica primului animal: * + » a. caracteristics()): . Malte instructinn’ * a = mew Caine Qs 5 System_out.println("Caracteristica celui de-al doilea” + a “animal: " + a. caracteristica ()): 2 Malte instructinat Cova ce atrage atenjia asupra acestui program este faptul ci toate cele patra metode caracterist ica () au aceeagi semniiturt (nume glist de parametri) ‘Acest lueru este permis deoarece nu exist dou metode cu aceeasi semmaiturl {in aceeagi clas’. Cum trei dintre aceste clase (Soarece, Caine, Pisica) cextind o a patra clasi (Animal), spunem c& metodele caracteristica() in clasele derivate redefinesc (engl. override) metoda caracteristica() din clasa de baz’, ‘Si analizim acum instructiunea urmitoare: Anim new Soarece(): fn aceast stati, varibila refering care este de ipul Animal desem- neazi un obieet de ipul Soarece, care ESTE-UN Animal prin mostenie (prin urmare,atribuirea este corect). Mai depart, intlnim in ead aceleag seevenie de cod ow Caine (): Cu alte cuvinte, variabila 2 refer’ (Ia momente diferite de timp) obiecte de tipuri diferite, dar similare (prin faptul e& sunt derivate din aceeasi clas Anima). Pentru a vi convinge de acest lucru,rulafi acest program. El va afiga urmitorele date Caracteristica primului animal: are culoarea gri Caracteristica celui de-al doilea animal: latra up’ cum se poate observa, apelurile metodei caracteristica(),prin intermediul referinjei a, au determinat apelarea metodelor corespunzatoare din clasele Soarece si Caine (si prin urmare, dous afigiri diferte), deoarece la ‘momentul fiectrui apel, variabila a referea un obiect de tip diferit. Poate cd unit dintre dumneavoastra se asteptau ca singura metoda apelati si fe cea din clasa ‘Animal, motiv pentru care rezultatul vi se pare anormal, dar el va fi perfect, cexplicabil dupa ce vom detalia nosiunea de apel polimorfic al unei metode, 128 Ca o paranteza, trebuie remarcat faptul c& inversarea rolurilor celor dowd clase nu este posibil fn cadrul acestui exemplu (normal de altfel, deoarece un animal nu este in mod obligatoriu un goarece): Soarece s = new Animal (); //INCORECT ‘Dupa cum am vazut anterior, in cadrul subcapitolului 5.1, mostenitea per- mite tratarea unui obiect ca fiind de tipul propriu sau de tipul de baz’ (din care este derivat tipul propriu). Accasta caractersticd este esenjialé deoarece permite mai multor tipuri (derivate din acelasi tip de date) s& fie tratate uni tar, ca si cum ar fi un singur tip, motiv pentru care acceasi secventii de cod va fi funcfionala pentru toate aceste tipuri, Pe de alti parte, apelul polimorfic al unci metode permite unui tip si exprime distinctia fafé de un alt tip simi- lar, alata timp cat amandoud sunt derivate din aceeasi clasi de baz. Distinetia este exprimati prin diferenja in comportamentul metodelor care pot fi apelate prin intermediul clasei de baz (in exemplul nostru, este vorba despre metoda caracteristica()). Polimorfismul permite scrierea de cod doar in raportcu clasa de baz, ca gi cum “am fi uitat” de clasele derivate. Totusi, cei mai mul}i programatori in spe- cial cei cu experienyi in programarea procedural, intimpind anumite dificulayi in njelegerea modului de functionare a polimorfismului Dificultatea poate fi intalnité si in cadrul programului din exemplul anterior. AMigarea celor doui mesaje este evident cea doritd, desi parcurgind codul sursi al programului, am putea avea impresia c& programul nu va functiona in acest ‘mod. Daciiprivim mai atent linia 38, observim ci metoda caracteristica() este apelati prin intermediul unei referinje de tipul Anima. Aga ci ne punem ‘mod logic intrebarea: este posibil si sie compilatorul cd variabila refering de tipul Animal refer un obiect de tipul Soazece, din moment ce se ape- leaza metoda acesteia din urma? De unde stie compilatorul e& este referit un obiect de tip Soarece, gi nu un obiect de alt tip (de exemplu, Pisica sau Caine)? Rispunsul este cB, de fapt, compilatorul nu stie acest lucru. Pentru a injelege mai bine aceast’ problema, este necesari o examinare mai atent& a noun de legare. ‘Conectarea unui apel de metodi de un anumit corp de metoda poarté numele de legare (engl. binding). Cand legarea are loc inainte de rularea programului respectiv (cu alte cuvinte, in faza de compilare), spunem cf este vorba despre 0 legare statica (engl. early binding). Termenul este specific programirii orien- tate pe obiecte. in programarea proceduralii (gen programarea in C sau Pascal), nofiunea de legare staticd nici nu existd, pentru c& toate legaturile se fac in mod stat in programul anterior, compilatorul nu stie ce metoda caracteristica() 125 (dinclasa Animal, Soarece, Pisica sau Caine?) shapeleze, avind doaro referinjlde tipul Animal. Solujiaconstdinsi in legarea tarzie (engl. late bind- ing). Cunoscuta si sub numele de legare dinamicd sau legare tn faza de execuie (engl. dynamic binding, run-time binding), legarea tirzie permite determinarea in faza de executie a tipului obiectului referit de o variabili referin(a si apelarea metodei specifice acestui tip (in exemplul nostru, metoda caracteristica() din clasa Soarece). Mecanismul de apelare a metodelor determina in mod ccorect metoda care trebuic apelati io apeleazi, Legarea este un fenomen care are loc automat - nu este atribufia programatorului si decida daci o metoda este apelaté prin legare statied sau dinamic ‘Am ajuns la momentul in care tebuie si conturim diferenja dintre redefini- rea (suprascrierea) unei metode si suprainedrcarea ei. Cu alte cuvinte, overrid- ing vs. overloading. Finalul capitolul 2, secjiunea 2.6, a prezentat nojiunea de supraincarcare a metodelor. Recapituland pe scurt informaile precizate acolo, supraincarcarea metodelor permite existenfa in interiorul aceleasi clase a mai multor metode cu acelasi nume, dar cu lista diferit de parametti (prin uurmare, cu semnaturi diferite). Astfel, putem avea o metod’ int max (int a, int b) siometoda int max(int a, int b, int c),ambelein ccadnul aceleiagi clase. Evident 8, analog, putem avea prima metod? ceadrul uunei clase de bazi gi cea de-a doua in cadrul unei clase derivate din clasa de bara. Pe de alté parte, nojiunea de suprascriere (redefinire) se bazeazsi toemai pe ideea ci metodele trebuie si aibe aceeasi semi ‘derivate din clasa de bai (vezi exemplul din aceasti sect ‘cele douti concepte este in acest moment clar definité Cele dow concepte pot provoca uncori greseli de programare greu dete tabile, in cazul in care nu sunt folosite corect. Iati un exemplu sugestiv: si presupunem c& metoda caracteristica() din clasa Soarece arfi avut de fapt urmatoarea defini: sii se afle in clase 1e), Diferenja dintre ‘public String: a 1} return “are blana eri: a eteristica (int i) Poate ci acest antet ar fi fost o gregealii neintenfionati a programatorului, sau pur si simplu, ar fi fost cova intenjionat, Ce s-ar fi fntimplat in aceasté situ: ajc Ia executia liniei 38 din exemplul nosteu’ Cert este c& aceasta mu ar fi fost interpretata drept o eroare de catee compilator. Programul ari rulat si ar fi afigat rezultatele: Caracteristica primului animal: necunoscuta 126 caracteristica celui de-al doilea animal: latra Poste ci vi se pare ciudat rezultatul execufiei versiunii modifcate a pro- gramului. Si vedem ce sa intamplat de fapt. Deoarece in clasa Soazece, noua metodi caracterist ica() are o semnitur diferté fa de metoda cu acelagi nume a casei de baz, am realizato supraincdrcare a acelei metode, si nu o redefinre a ei, Astfelclasa Soarece are acum doui metode ca racteristica|) diferite: una mostenit prin drivarea din clasa de baz gi cealalts prin supraincircarea metodei din clasa de baz8. In urma apelului Gin linia 38 se va executainsi metoda mostenith din clas de baza, si nu cea supraincircata,deoareceaceea corespunde ca semnitur, Astfel, mesajul afigat este “necunoscuta”. Desi se itenfionaseo redsfnie a acelei metode, datoritifaptlui 5-0 erst a defnirea antotuui e,rezltatal naa fost col atepat. Totus, compila- torul a presupus ca intentia a fost de a supraincrca metoda si nu de ao redefini, moti pent care nu a afigat nici o eroare. Evident cd acesta nu este un apel polimorfc de metoda. Odatd ce a fost depistatéeronrea ea poate finlturatt Simpla, isk ext infnt mal gre in cazul vnor aplicatit ms complexe. La fel de adevirat este fapt ck uncor exact acest comportament este dort. Programa tori avansafi vor sti cu siguranfa cum sa “jongleze” cu cele doua nojiuni. Cei Conpara doua forme dupa arie + + String toString ——>Meroda uzwala pentru seriere hh abstract class Shape at bo private String name: abstract public double area(): public Shape( String shapeName) moe name = shapeName > final public b c fan lessThan (Shape ths) d | returm area () < ths.area (Qs oo a 1 publle String toString) » 3 returm mame +", avand aria" + area(s oo nainte de a trece mai departe, si rezumim cele patru tipuri de metode ale unei clase: 1, Metode finale. Apelul lor este rezolvat inc de la compilare. Folosim 132 metode £inal doar atunci cind metoda este invariants de-a lungul ie rathiei (adicd atunci cdnd metoda nu este niciodatd redefinita); 2. Metode abstracte. Apelul lor este rezolvat in timpal executiei, Clasa dde baz nu furnizeaza nici o implementare a lor si este abstracta, Clasele derivate trebuie fie s4 implementeze metoda, fie devin ele insele abstracte;, 3. Metode statice. Apelul este rezolvat la compilare, deoarece nu exist’ object cate si le controleze; 4, Alte metode, Apelul este rezolvat la executic. Clasa de baz furnizeaza o implementare implicita care fic va fi redefinita (partial sau total) in clasele erivate, fie acceptat& nemodificat. 5.3. Exemplu: Extinderea clasei Shape fn aceastkseojiune vom implementa clsele derivate din casa Shape $i vom prezenta cum sunt ele utlizatefatno manierd polimorfick. Tati enungul probleme: Sortare de forme. Se citesc N forme (cercuri, dreptunghiuri sau patrate). Sai se afgeze formele ordonate dup arie. Implementarea claselor Circle, Rectangle si Square, prezentatd in Listing 5.5 este simp si nu ilustreaza aproape nici un concept pe care st nu-1 fi prezentat deja, Singura noutate este c& clasa Square este derivatd din clasa Rectangle care este, la rindul ei, derivati din Shape. La implementarea fieciei dintre aceste clase trebuie: 1. si definim un nou constructor, 2. ninim flecare metodi care nu este final sau abstract pentns m si o acceptim nemodificat’, Pentru fiecare astfel de metodi care nu corespunde cu necesiigile clasei trebuie s% furnizim 0 now definire; 3. siidefinim fiecare metod abstract; 4, st adaugiim alte metode dact este necesar, 133 1:3, EXEMPLU:EXTINDEREA CLASEI SHAPE: Listing 5.5: Codul complet pentru clasele Circle, Rectangle si Square, ‘care va fi salvat in 3 fisiere sursi separate Te elazele Circle, Square vi Rectangle ‘toate sunt derivate dix Shope 4S CONSTRUCTORI: (a) cu raza pir. cere. (b) ew latura 5 4 pir. pairar, (ec) ew lungime si latime pir. dreptanghi ‘ metede. peblice = +s double areai)——>implementeaza metoda abstracta din Shape +S ATENTIE: Fisierul trebuie separat in 3 pentru compilare! hi public class Circle extends Shape nt bp vate double radius ‘public Cirele(double rad) « f © super(*Cirete"): radius = rads moo public double area) a 2 return Math. PI + radivs + radius: od sy > public af private double length: private double width; 6 Rectangle extends Shape public Rectangle (double len, double wid) bh this(len, wid, "Rectangle od Rectangle (double len, double wid, String name) » super (name) Tengih = lens width= wid: {public double area() of “% retura length + width 63, EXEMPLU:EXTINDEREA CLASEI SHAPE “1 S public class Square extends Rectangle i public Square(double side) “ ‘ super(side, side, "Square"); a ” Pentru flecare clas am seris un constructor publie simp care permite inii- alizarea cu dimensiunile de baza (ra pentru cercuri,lungimea laturlor penis 0 && imp. lessThan (alj—1); --j) 5 c e aj) = atj-u * ’ ® au) so “4 5.4 Mostenire multipli ‘Toate exemplele presente pind acumn deivas o cli dinteosinguri clash de baza. in eazl mosteniit muple o clas este deriva din mai mult de o clasi de bazi. De exempl, putem avea clasele Student si angajat. Din acess clase ar putea i derivati oclasé Anga jatStudent. Desi mostenirea mutipl pare desta de atrgitoare iar uneleimbaj (cum ar fi CH) chiar o implementeara, ea este imbibatt de subi care fae pro- icotarea clselordeosebit de difcli. De exemplu, cele dou clase de baz ar putea congine metode care av aceeasisemnituri, dae implementie diferte sau ar putea aveaatibute cu acelaginume, Care dintre el a rebut folosit? Din aceste motive, fava nu permite mostenirea mulipti. Java farizeazi {nsio altemativa pentra mostenirea multplé prin intermediul conceptului de interfaga. 138 5. roneere 5.5. Interfete Inierfaga in Java este cea mai abstract clas posibili. Ea consti doar din metode publice abstracte si din tribute statice si finale ‘Spunem cdo clasi implementeazii 0 anumit® interfata dact furnizeaza de- finiji pentru toate metodele abstracte din cadrul interfejei. O clas& care i plementeazi o imterfaja se comporté ca si cind ar fi extins o clast abstract precizatd de edtre acea interfata. in principiv, diferenja esengiali dintre o clas abstracta si o interfap este 8, desi amindous furnizeaza o specificatie a ceea ce clasele derivate trebuie si faed, interfaja nu poate furniza nici un fel de detaliu de implementare sub formé de atribute sau de metode implementate, Consecinja practic’ a acestui Jucra este ef derivarea din interfeje nu suferi de problemele potenfale pe eare Te are mostenirea multipli, deoarece nu putem avea implementiri diferite pentru acceagi metodi, Astfel, desi o clasi poate si extindl o singuri clasi, ea poate si implementeze mai mult de o singura interfa’. 5.5.1 Definirea unei interfete Din punct de vedere simtactic, nimic nu este mai simplu decSt precizarea interfeje. Interfaja arata ca 0 declarajic a unei clase, doar ct foloseste cuvintul cheie interface. Ea consti dintr-o list de metode care trebuie declarate. Un exemplu de interfata este Comparable, prezentata in Listing, 89. Interfaja Comparable precizeaza dou metode pe care orice clas derivati din ea trebuie si le implementeze: compareTo () si lessThan(). Metoda compareTo () se va comporta similar cu metoda cu acelasi nume din clasa String. Observaficiinu este necesar si preciziim faptul ci aceste metode sunt public sau abstract, deoarece acest Iueru este implicit pentru metodele uunei interfef. Listing 5.9; Imerfaja Comparable Public interface Comparable wt + int compareTo( Comparable rhs): ‘boolean lessThan (Comparable rhs ): 5.5.2 Implementarea unei interfete (O clas implementeaza o interfag in doi pasi: 139 33 INTERFETE. 1, declari ci iplementeaz’ interfaja; 2, defineste implementiti pentru toate metodele din interfa Un exemplu este prezentat in clasa din Listing 5.10, in care se definesteclasa My Integer. Clasa My Integer are un comportamentaseménator cu al clasei Integer, din pachetul java. ang, fn linia 1 se obscrva cd atunci cind implementim o interfat8folosim cuvan- tul cheie implements in loc de ext ends. in aceast clash putem serie orice metode dorim, dar trebuie si definim cel putin metodele din imerfaa. Imerfaja «ste implementati in lnile 27-36. Remarca fptul cd trebue si implementim exact metodele precizate in eadrlinterfefei (compareTo, LeseThan). Din acest motivaceste metode au ca parametru un obiect de tip Comparable gina un MyTnteger. (0 clasi care implementea2i o interfaj poate fi extinsi cu condifia si nu fe final. Astfel, dack nu am fi declarat clasa MyTneeger ca find final, am fi ‘putuo extinde. O clasi care implementea2i o interfays poate tousi si extind $0 alti clas. De exemplu, am f puut in prineipiu, serie: public 1s Mylateger extends Integer imp! nts Comparable Acest cod este incorect doar pentru c& Integer este o clasi final care nu poate fi astfel extins Listing 5.10: Clasa My Tnteger care implementeaza interfaja Comparable \Tinal public class Myloteger Implements Comparable a {public Mylnteger(int value) se tS thts value = value ) public String toString) af return Integer. toString (value }: od Ss public int intValue 0. af > return value: = 5 public boolean equals (Object rhs) ‘ return rhs in value cook Mylnteger && (Mylnteger) rhs), value a % Mimplementarea interferel 2 public. Boolean lessThan (Comparable rhs) af 3 return value < ((Mylnteger) rhs). value 4 & publle Int compareTo( Compa: af be return value < ((Mylnteger) rhs). value ? —1 value == ((Myloteger) ths). value 7-0: wd ble rhs) private int value: ” 5.5.3 Interfete multiple ‘Asa cum am menfionat mai devreme, o clasi poate sit implementeze mai ‘mult de o singur’ interfagi. Sintaxa pentru a realiza acest lucru este simpli. last poate implementa mai multe interfeje pr 1. precizarea interfejelor pe care le implementea 2. implementarea tuturor metodelor din interfefe Interiaja este cea mai abstract clasi posibili si reprezinta o solutie elegant la problema mostenirii multiple 5.6 Implementarea de componente generice ‘Si ne reamintim ci unul dintre scopurile principale ale programiri orientate pe obiecte este suportul pentru reutilizarea codului. Unul dintre mecanismele importante folosite pentru indeplinitea acestui scop este programarea generica ddaci implementarea unei metode este identic& pentru mai multe clase (cu ex- cepfia tipului de baza al obiectului) se poate folosi o implementare generica pentru a descrie functionalitatea de baz’. De exemplu, putem scrie o metoda care si sorteze un sir de elemente, Algoritmul pentru aceast’ metoda este in- dependent de tipul de obiecte care sunt sortate, deci putem folosi un algoritm generic 141 Spre deosebire de multe dintre limbajele de programare mai noi (cum ar fi C++) care utilizeaza sabloane (template) pentru a implementa programarea ‘genericd, Java nu oferi suport pentru implementarea directa a programa gene- rice, deoarece programarea generic& poate fi implementati folosind doar con- ceptcle de bari ale mostenirii. in aceasti sectiune vom prezenta cum pot fi implementate metode gi clase generice in Java folosind principle de baza ale rmoste Ideea de baza fn Java este ci putem implementa o clas generic folosind 0 superclasi adecvati, cum ar fi Object. in Java, dac o clas nu extinde o alti clas, atunci ea extinde implicit clasa Ob ject (din pachetul java .lang). Ca © consecin{,flecare clasi este 0 subclasi a lui Object. ‘S& considerim clasa MemoryCe11 din Listing 5.11. Aceasta clasi poate si rejind un obiect de tip Object. Deoarece Object este clasi de baz pen- tru orice clask din Java, rezulti c¥ aceasta clas poate s& stocheze orice fel de obiecte. ing 5.1 j= MemoryCell Clasa generic’ MemozyCell 0 && imp. lessThan (alj—1): ~-3) c e au) " ) 8 aul bd “1 atin imp: Listing 5.14: Citirea unui sir de numere intregi si ordonarea lui folosind un algoritm generic ‘Import ios: //pacher defini anterior spublie class Sortins i Varogram de test care citeste mumere intregi Wleate wnul pe linie), le ordoncaza si apot le afiseaza publle state vold main(String [} args) c W Weiterte un sir de intregi hh System. out. print("Blementele sirutui fs IMt [] sie = Reader. readIatArzay (2 th Heonversie ta un sir de Mylnteger 's Mylteger{] sisNow = new Mylnteger sir. length J: for (int i= 0; i < sirvtength; ++i) an ts SipNoul i] = mew Myloteger(sir[i]): 4% Haptica metoda de sortare 144 5.3, CLASE INTERIOARE INNER CLASSES) Sort. insertionSort(sieNou}: dM Hafixeaza rezultatul sortarit > System-out.printin("Rezultatal sortarii: ")s mM for(int i = "0: 4 © sisNou. length: +44) sot System. out. printia (si Se » oul): 5.7 Clase interioare (inner classes) Clasele interioare reprezinti un tip special de clase care, dup cum le spune si numele, sunt definite in interiorulaltor clase, Clasele care includ clase inte- rloare se numese (evident) clase exterioare. Clasele interioare sunt o facilitate important a limbajului Java, deoarece ne permit si geupim clasele care apartin {in mod logic una de celalalté si si controlim nivelul de viziblitateintre aceste clase, Clase interioare reprezinti.un concept distinct de comporitia claselor (0 clasi are un atsibut de tipulaltei clase). Diferenjele le vefi injelege aprofundind: tueptat noyiunea de clas interioar, Necesitatea claselor interioare nu este deloc evidenta (cinstit vorbind, cat dintre programatorii de Java care citese aceasta Iucrare au auzit sau au folosit clase interioare?), Sperm ca exemplul din aceastd carte si clarifice utilitatea lor. ‘Asa cum era de asteptat,o clasi interioara se defineste in cadral alte clase care 0 cuprinde: 2 Clasa exterioara public class Scrisoare u © class Destinatie 7 ot 7 N Halte posibite clase interioare N Hatribure si metode ale clasel exterioare 145 $7. OLASE INTERIOARE INNER CLASSES) fn exempll de mai sus casa exterioardeste Scr soaxe, iar cea interioart ste Dest inate, Pentna face acest exempli funejional, cea iil surst Serisoare. javacain Listing 5.15. Listing 5.15: Clasa Scr soare care cuprinde clasa interioari Dest inatie ire t+ Clase exterioara Serisoare ipablic class Scrisoare a + Clase interioara Destinatie + class Destinatie wt (ee Destinatia unet sertsort.a/ private String dest |S fee Creaza 0 destinatie pentru scrisoare. +/ m Destinatie(String dest) >t " this dest = dest: bod fas Obtine destinatia serisorti/ 2 public String obtineDestinatia() > 1 B return dest: so) x m f4 Trimite serisoare te adresa specificate.#/ % public void trimiteSerisoare( String dest) =f hv” Destinatie & = new Destinatie (dest ): 4h System-out. printin("Serisoarea a fost trimisa * + uo “la -destinatia: "+ 6, oblineDestinatia(Q)t > fee Programul principal. +/ % public statle vold main(String (] > tu — Serisoare s = mew Scrisoare (s | Hartmite serisoarea in SUA" ti s.trimiteSerisoare (SUA): 146 5.3, CLASE INTERIOARE INNER CLASSES) ran] “) Prin rularea acestui exemplu se va objine urmitorul rezultat: Serisoarea a fost trimisa la destinatia: SUA Daci privti cu atenfie rezultatul compiliii figieralui Scr isoare. java, veji observa aparijiaa doua fgiere: Scrisoare.classsi ScrisoaresDes- tinatie.class, Cum rezultatul compiliti fiectrei clase este un fisier cu extensia . Class, care conjine bytecode-ul pentru clasa respectiva, este normal ca $i oclasd interioara si produc&.unfisier . class, care si conjina bytecode-ul produs de compilator. Pentru a face sesizabili legiura dintre clasa exterioari si cea interioara chiar si in situajia in care figierele sursi ale claselor nu sunt Aisponibile, creatorii limbajului Java au ales ca fiecare clas interioara si res- pecte o formuli stricti in ceea ce priveste numele fisierului .class care fi ccorespunde. Aceasta formula arata astel: NumeClasaExterioara$NumeClasaInterioara fn exemplel nostra, clasainteioari Destinatic, care este utiliza in metoda trimiteScrisoare (). arti ca orice alta clasi, Singura dferenté pare afi faptulcdeste defini n intrionl alte clase. Vom vedea mai ticia exists alte diferene mai subtle. fn exemplul anterior clasa interioars Dest inat ie mu a fost utiliza in smod direct in programa principal, dar nimic au ne impiedic si o uilizim. Usilizarea in metoda main a cast interioare se realizes ast: public static vold main(String (] args) Mereara 0 serisoare Scrisoare s = new Scrisoare (): ‘ Mavimite serisoarea_in “SUA” 7 S-trimiteSerisoare ('SUA"): Wereata 0 alta destinatie * Destinatic d = s.new Destinatic ("Ca ‘Sintaxa pentru crearea nei clase interioare este neobisnuita si poate pune {in incuredtura chiar si programatorii care au ceva experienfl in Java. Dupii cum se poate observa, pentru a crea direct o instanf a claset interioare (in exemplul nnostru, ), este necesara uilizarea unei instanje a clase exterioare (in exemplul nostru, s). Astfel, nu este posibil’ crearea unei instanfe a clasei interioare, 147 $7. OLASE INTERIOARE INNER CLASSES) act nu este deja creaté o instangi a clasei exterioare. Limbajul Java impune o astfel de strategie, deoarece obiectul interior (cu alte cuvinte, instanga clasei interioare) este conectat la obiectul exterior (instanjaclasei exterioare) din care ‘este creat. Aceast& conexiune este specifica doar claselor interioare si va fi Jes Exempla de membru static al clasei statice.«/ a le static void TQ) an 4 publte static Destinatic catre(String dest) » of = return new Destinatie( dest}: aan) MN fee Trimite serisoare la adrera specificata./ public static void trimiteScrisoare(Destinatic 4) » et System.out. printin("Serisoarea fost trimisa” + a Ta destinatia: " + d-obtineDestinatia()): ooo © fee Programul principal .»/ & public stathe vold main(String [J args) o « Destinatie d= catre("Canada"): 5.3. CLASE INTERIOARE NNER CLASSES) » Marimite serisoarea la destinatie . trimiteSerisoare (a): a Folosind clase statice interioare, nu a mai fost necesari crearea unei instante a clasei exterioare Scrisoare. Dupi nularea programului se va afiga urmi- tonal rezulat: Scrisoarea a fost trimisa la destinatia: Canada 5.7.3 Clasele membre nestatice ale clasei exterioare Clasele membre nestatice au fost prezentate pe larg la inceputul acestui sub- ‘capitol, motiv pentru care au mai rimas putine detalii de adaugat: ‘spre deosebire de clasele interioare statice, cele nestatice nu pot avea ‘membri static; * uncori este necesara referinfaclasei exterioare, care este objinuti folosind sintaxa NumeClasaExterioara. this. in exemplul nostry, referin- {a la clasa exterioara se objine prin Scrisoare. this: 5.7.4 Clase locale (© clasi localé poate fi creati in cadrul unei metode, cain exemplul urmitor: Listing 5.17: Exemplu utilizare clase locale ipublic class Scrisoare sf (fee Metoda ce cuprinde 0 clara interioara/ lie String eatre String dest) » vclasa interioara Destinatie " v 8 class Destinatic 5 t ' Private String dest 153 $57. CLASE INTERIOARE INNER CLASSES) " Jee Creaza o destinatie pentru serisoare.+/ » Destinatie(String dest) » i » this dest = dest e ’ x Jes Obtine destinatia serisorlt./ * public String obtineDestinatia() ™ C 4 a , 5 , ” return (new Destinatie (dest )). obtineDestinatia(): an) Mee Trimite serisoare la adresa specificate.+/ public void trimiteSerisoare( String dest) » ” System, out. printin("Serisoarea a fost trimisa” + ” “la destinatia: "+ catre(dest)): an) A fee Programul prineipal«/ fb public statle vold main(String () » ¢ a Serisoare s = new Serisoare(): “ Mirimite serisoarea la destinatio a S-trimiteserisoare (*Romenia” ): oo a Ene evident faptl ck aplicayia nu are o utltate practic, din moment ce atigeazi chine stringul pe care fl primegte ea parametr. Ea repreznti doar un pretext penta vedea cum se ereazio clash interioari local, Este ugor de ob- servat ci metoda cat re cuprinde casa interioard Dest inat ie fn interional ci, Find defnitainaceasti metoda, clasa Dest inate este accesibilé doar in ceadral metodei, incerearea dea o utiliza in afara metodei respective produce 0 ‘roare la compilarea programy Prin rularea program se objine urmaoralrezultat Scrisoarea a fost trimisa la destinatia: Romania Pentru a complica gi mai mult lucrurile, trebuie si addugiim c¥ o clasi in- terioar& poate fi definita si n cadrul unui bloc de instructiuni, asemanator cu ‘exemplul anterior, in care metoda catre este modificata astfel: 154 5.3. CLASE INTERIOARE NNER CLASSES) public String af re (String dest) b te(dest m) oot ‘ v clase interioara Destinatie ‘ class Destinatic . fi o private String dest » Jee Creaza 0 destinatie pentru serisoare.+/ ® Destinatie(String dest) “ i a this dest = dest: " ’ » (ue Obtine destination scrisorti#/ ® public String obtineDestinatia() E C eB return dest; = , = 1 » return (new Destinatie (dest )). obtineDestinatia () soy > else » A Desi aceasti utlizare pare destul de curioasi, clasa interioari Dest ina~ ‘ee poate fi definiti in cadrul unui bloc de instrucyiuni (in cazul nostra, in- strucfiunea i), find vizibila doar in acel bloc. Pentru a risipi eventuale urme de indoiald este util de reyinut cd definirea clasei Dest inat ie in cadrul in- strucjiunii ££, nu iseamni cl aceasti clasi este creat in funetie de indeplinirea ‘condijiei din 1. Clasa va fi creat ca orice alt clasi la compilarea programu- lui, dar nu va putea fi utiliza decat in cadrul blocului de instruejiuni in care a fost definta. Clasele locale sunt foarte rar uilizate din cauza codului mai putin lizibil pe ‘care il creaza (noi nu le vom utiliza deloc in cadeul acestei lueriti). Totusi ele ‘exist gi pot fi utilizate in situti in care programatorul considera cd este nevoie deel. 158 $57. CLASE INTERIOARE INNER CLASSES) 5.7.5 Clase anonime Daci exemplele anterioare v-au creat impresia ei nojiunea de clasit local este mai “deosebiti, pregitii-vi si va intiriti aceasti convingere, urmarind cu ‘atenjie modul de definire al claselor anonime. Pentru o mai bund ingelegere, iat ‘un exemplu ce defineste o class anonims: Listing 5.18: Model de definire a unei clase anonime ae bt Clasa exterloara Serisoare ‘public class Scrisoare a {public Destinatie trimiteg. >t : return new Destinatie() : i ” private String dest?; E public String obtineDestinatia() ® C 5 ) " }: 7:7 este mecesar la definirea elaselor ononime an fee Programul principal .»/ > publle state vold main(String () =f Germania Serisoare s = new Serisoare(): a Destinatie d= s.trimite (: elass Destinatie mt >. private String dest “ Analizind exemplul intalnim dou clase, Scrisoare si Dest inatie, si'o modalitate mai pujin intilnita de definire a metodei trimite. Aceasti ‘metod’ combina procesul de returnare a unei instanfe a clasei Dest inatie, la linia 8, cu cel de definite a unei clase fri nume (anonima), la liniile 9-16, Clasa anonimé reprezintio subclasi a clasei Dest inat Se, datoriti faptului cd © system.out.printin(m este instante a clasel * + * sli l getName): 4 " Eroarea este datoratd faptului c& operatorul instanceof nu poate fi folosit decat in conjunctie cu numele clasei (Dacia), si nu cu un obiect, de tipul Class (Dacia.class). Pentru a corecta aceasti eroare, se 164 58. IDENTIFCAREA TPURILOR DP DATE IN FAZA DE EXECUTIE utilizeaz metoda isTnstance () , inlocuind conditia din instructiunea if, cu condijia c [i] . istnstance (m). Rezultatul executiei progra- ‘mului astfel modificat este: m este instanta a clasei Dacia upd cum se poate observa, metoda isTnstance () oferi un mod di namie de a apela operatorul instanceof. Ambele variante produc insi rezultate echivalente Exist o difereny important intre operatorul instanceof (implicit si metoda, is Instance (), pentru c& sunt operatit cu rezultat echivalent) si compararea folosind obiecte de tipul Class. Diferenfa este vizibila la aflarea informatiilor despre clase. Operatorul instanceof verific dact un obiect este o instangi .unei clase specificate sau a unci clase derivate din clasa specificata, in timp ‘ce compararea obiectelor de tipul Class nu fine cont de mostenite, ci doar verific strict dacit obiectul respectiv este o instanja a clasei specificate sau nu, Pentru a verifica afirmaile anterioare, iat un exemplu: + Masing m 2 System out. yew Dacia: atin ("m instanceof Masina * + : (m instanceof Masina )); System out. printla(*m instaneeot Dacia "+ 7 (im instanceof Dacia )): 1 System out. peintla("m. getClass () == Masing class "+ I (m. getClass () == Masina vs System out. printin("m. getClass () == Dacia.class "+ fa (m, getClass () == Dacia. elas )): 59) Secvenfa afigeazi urmitorul rezultat: instanceof Masina true instanceof Dacia true «getClass () == Masina.class false sgetClass() == Dacia.class true Peery 5.8.2 Mecanismul de reflectie (""reflection") Acest paragraf prezinti concepte mai avansate, care nu sunt necesare pentru {njelegerea informagii din restul lucriri, Dac’ nu suntei direct interes 165 conceptul de reflection, pute sri deocamdatt peste els vti putea event ute- ‘ior, cind bagajul de cunostine acumulat vi va permite o fnjelegere mai usoar ahi Pentru a putea aflatipul unui anumit obiect pute utiliza oricare metodele antrioare, dar trebuie save in vedere 8 exists o anumit limita. Dezavantajul const in fapule& ipuile de date trebuie si fie cunoseute fn faza 4e compilare, chiar dat cle sunt utilizate in faza de execusie. Cu alte euvine, compilatoral uebuie si eunoasca toate clasle care sunt utlizate pent identic ficarea tipurlor de date in faza de executie a programului. La prima vedere nu pare a fio limitare, dar poate devent in situayia tn care este necesart instanjerea unei clase care nu este disponibilt masini viruale VM in moment compilri, Aceasta sunt probabilin acest momenta science- fiction, dar in apticaile concrete (tn special cele client-server) aceastsituaje fu constiuie o raitate, De exemplu,tntr-un fier putem avea un gir de octeyi care stim cl reprezintéo clas, in faza de compilare, compilatorul nu poate afla nici o informaje legatt de acel sir de octefi, deci uilizarea nei asfel de clase pare imposibits. Din feicre, platforma lava oferto soluie pentru aceast pro- blemi: mecanismul de reflecje (reflection). Reflecia este un mecanism prin care se pot determina informa despre o clas (numele clasei, numele metode- Jor, sumele constructorilor, ete.) flr ca acea clasi si fle cunoscuti compil ‘orulyi in faza de compilare Clasa Class prezenta in paragraful anterior suporth conceptul de re- Acti, dar majritatea claseor specializate pentru acest mecanism se g8sese in pachetul java. lang. reflect. Citevadinteaceste clase, Constructor, Field, Method, vor fi prezentate mai pe larg pe parcursul acestui subeapto. fn general, mecanisinul de reflefie este utiliza in mod direct destul de rar de programator, dar exist situafi in care sunt de folos anumite informa legate de 0 clas8, De aceea vom prezenta, cu ajutorul unor exemple simple, cum se pot ala informa utile despre o cast “Mediul de programare Java are a disporitie un API destul de bogat pentru 4 asigura funcjonalitatea mecanismului de refleyie, AP-ulreprezintd clasele, obiectele si interefele din masina virwala JVM si permite operafi de tipal: © doterminarea clasei a cdteiinstangi este un anumit obiect; + objinerea de informajii despre modificatorii de acces ai casei, despre atribute, metode, constructor si superclase; + objinerea de informatii despre constantele si metodele declarate ints-o interfayts 166 58. IDENTIFCAREA TPURILOR DP DATE IN FAZA DE EXECUTIE « instangierea unei clase, al cdrei nume este cunoscut doar in faza de exe= cue: ‘© modificarea valorii unui atribut al unei clase, chiar daca numele atributu- lui este cunoscut doar in faza de execu * apelarea unei metode a unei clase, chiar daci numele acestei metode este ‘cunoscut doar in faza de executie Obfinerea de informayii despre o clasit entra a aflainformajii despre o clast trebuie si objinem obiectul de tipul Class asociat clasei respective, pentru ci acel object define toate informagile legate de clasi. Folosind acest obiect se pot apela diverse metode ale clasei Class, care rewmeazi obiecte de tipul Constructor, Field, Method, ‘corespunziitoate constructorilor, atributelor si respectiv metodelor definite in cadrul clasei, De asemenea, un object Class poate reprezenta chiar i 0 inter- fa, situapie in care se pot afla informatii despre constantele definite, metodele declarate ete, Evident, nu toate metodele clasei Class sunt potrivite inte-0 ast- fel de situafie. De exemplu, nu este normal apelul metodei get Constructors, deoarece o interfafa nu are constructori. ‘Agadar, primul pas care trebuie realizat pentru o objine informaii despre 0 System out. printia(s) ") = catch (Exception ) >t a] Exemplele prezentate de-a lungul acestui subeapitol denota faptul cit mecani ‘mul de reflecfie permite ca informatiile despre obiecte si fie complet dete nate in faza de executic, fri nici o interventie in faza de compilare. Analizéind ‘comparativ identificarea standard a tipului de date gi mecanismul de refleeie se poate spune ci cea mai importanti diferenja dintre cele dous este cd in primul ‘caz compilatorul verified in faza de compilare clasele, in timp ce in cel de-al doilea caz, clasele sunt verificate in timpul fazei de execute. Rezumat ‘Mostenirea este o caracteristic puternic’, flind esenfa programari orientate pe obiecte gia limbajului Java, Ea permite abstractizarea funcjionalitajii in clase abstracte, pentru a deriva apoi din aceste clase, alte clase care implementeaza si ‘maiese functionalitatea de baz ‘Cea mai abstract clas, care nu implementeaz’ nimic poate fi specificati utilizand o interfaja. Metodele specificate de o intefafa trebuie definite de clasa ‘care 0 implementeaza. Un alt tip special de clase sunt clasele interioare, care sunt clase definite fn friorul altor clase, Desi mai pusin utilizate decdt celelalte tipuri de clase, ele oferi facilitigi specifice i au avantaje importante Uneoti este necesar si identificdm tipul unui obiect in faza de execusie fa programului, Desi aceasté facilitate nu va fi utiizatd in cadrul acestei lu- ‘ri, ea reprezinta un element sine qua non pentru programatorii care ajung s& foloseasca tehnologii client-server cum ar fi CORBA sau EJB. 1B 58 IDENTIFICAREA HPURILOR DE DATE IN FAZA DE EXECUTIE Capitolul urmator este unul mult asteptat, prin prisma numarului de referti de care a avut parte de-a lungul capitolelor anterioare. Este vorba despre “Tra tarea excepyiilor”. Nofiuni fundamentale cast: operator unar prin care o clasi este convertti Ia alti casi. clas abstracti: clasi care nu poate fi instantiat dar care inglobeazi func- sonalitatea comuni a claselor derivate din ea. las anonimi: class locali care nu are nume. lasii de baz: clasi din care se derivenzi/implementeaza alte clase. clasi final: clas care nu mai poate fi derivats. las interioari: clasi definiti in imteriorul altei clase, las derivati: clasi complet noua care mosteneste funcjionalitatea clasei e bazi. ) Pentru o mai bund injelegere a blocului £ina..1y s& considera programul din Listing 6.3, in care avem o aplicajie care deschide (sau creaz’ daca nu exist) un fisier stocat pe hard-disk si serie in el un sir de nume Listing 6.3: Program de test pentru clauza finally \Tiktane Fister TestPinally java sImport java. ios: bite ¢ TestPinally (64. PRINDEREA §1TRATAREA EXCEPTILOR “ }) public static void main(String (] args) of + PrimtWeiter pw = ints = (307 S String meg nou wt mig = "Se incearca deschiderea fisierului ...°: System out. printla (msg); 5 pws new PrintWriter(new FileWeiter 0 Prisiersext™)}: S for (int i = 0: 4 < sutengths 140) ® t Ee pw. printin (si): EB ) sy Bs cateh (IOException ioe) » %mig_= “Exceptie 1/0 prinsa: * + ioe. getMessage () % System. out. printin (msg): >) = finally nt n it (ow t= nutty ” t a pw. close (): 2 System out printia("Fisierul @ fost inehis™ ot » System.out. printin("Fisierul mu a fost * + a “desehis”): Ff ) ey oo Programul afigeaza urmatoarele mesaje: Se incearca deschiderea fisierului Fisierul a fost inchis Totodatl, programul ereazi un figier numit £isier txt, in acelasi direc- tor cu fisierulsursi al aplicafei noastre, cu urmatorul conginut: 3 193 (64 PRINDEREA §LTRATAREA EXCEPTILOR. deci totul s-a executat fard eroare, iar iegirea din blocul try nu a fost brused. ‘Tolusi, instructiunile din blocul fina 1y s-au executat pentru cl a fost afisat mesajul "Fisierul a fost inchis*. ‘Si incercim acum si fnlocuim numele fisierului, fisier txt, cu o cale \test\fisier.txt, cu condifia ca directonul test SiNU existe pe partiia C: a hard-disk-ului dumneavoastr3, Ruldnd programul astfel modificat, se objin urmitoarele rezultate: invalid, eum ar fi Se incearca deschiderea fisierului. Exceptie 1/0 prinsa: c:\test\fisier.txt (The system cannot find the path specified) Fisierul nu a fost deschis fn aceasta sitaje, constrictor clase Fi Leitri tex aruned o excepfie de tipul 1OExcept:ion, pentru ci nu poate gisidirectorul test. sin consecinft ni poate crea iol £i5ier. txt. Excepja anancati este trata de bloc catch existent, care afiseaza mesajul "EXceptie 1/0... ". iar apo, -executii din nou instrucjiunile din blocul final ly, afigandu-se mesajul "F i- sierul nu a fost deschis™ Dupit cum se poate observa, blocul finally a fost execuatindiferent dac’ stuatia a fost de eroare (al doilen az) sau nu (primul eaz). Deoarece in blocul finaly ay fost liberate esurslealocate in blocsl try in cau tosin, foxul de seriere Print ter), putem considera blooal £3nal1y tin mecanism elegant de a "face curijenie” duph execufia codului din blocul try. ‘Sitatia de eroare prezentati anterior nu este singular, TOExcept Son pot fl generatd si ack directorul respectiv exist (dei cal este valid), dar aplicaia nu are drept de screre in acel directo, sau dact nu mai exist suficient spatiu pe dise pentru a serie date in figierl respectiv Cu sigurangi i programatori cu experieni in alte imbaje de programare (in special C++, unde aceasti none nu exist) se vor inreba daci exstenta clauzei finally este justfiatd. Nevoia de a avea clauza finally devine evident dacdanalizdm mai atent programul anterior, in cae, firi finally. flaxol de seriere arf putt f cliberat doar daci am fi plsatcodul in care bloc ccat.ch separ, ceeace ar fi dus lao duplicate intila a coduli 194 63, ARUNCAREABXCHPTILOR 6.5 Aruncarea exceptiilor Insime cao excepfie si fe prins, tebuie si exist, undevain cadrlclaselor utlizate,o secvenfé de cod care si arunceexceptiarespectiva. Exceptile pot aruncate ati de codul scris de damneavoastri cts codul dn clase scrse dealt programator (cum arf, excepile aruncate de casole predefnite fn platforma Java), sau chiae de masina virtual JVM. Indiferent de cine aruncdexcepti, este inttdeauna aruncatafolosind cuvanal cheie throw. 6.5.1 Instruefiunea throw Metodele Java arunci excepfiifolosind instrucyiunea throw. Instrucjiunea ‘cheow este urmati de un singur argument, care trebuie si fie o instanja a unei clase derivate din clasa Throwable, gi are urmitoarea form: throw instantaClasaDeExceptit ati cteva exemple de utilizar: throw new Exception (): Exception © = new Exception (): throw e: (temperatura initiate @ ceaintus int temperature = 30; Mealeule intermediare Uconsideram ca temperatura la care ceaial Vn este ince fierbinte, este de 40 de grade it (temperature > 40) ‘ Meeaiul este Joarte flerbinte si mu poate fi bout ‘“Wadeei suntem “intro situatie de eroare, “moriv pentru care aruncem 0 exceptie throw new TeaTootlotException () 19s (65. ARUNCAREA EXCEPTHILOR Incereareade a arunca drept exceptie un obiet care nu este i ddeexceptie, este semnalatidrepteroare de citrecompilatr. in momentul arunciit unei exceptit se ealizear8 mai multe Iucrusi: mai {ntti se crear object de tip excepfie, tn acelasi mod in care se ereaz’ orice ‘object Java, prin folosirea cuvantulu cheie new. Apoi, se intrnupe exceuj normalA a instrcfunilo, iar mecanismul de tratare a exceptilr,aflat in JVM, pra sarcina de acuta scevenja de cod care trateaz& excepfia respectivs, pent. a putea continua exeeutia program CCrearea obiectulu de tip exceptie consti de fapt in apelul unui constructor a clase deexcepfie. Aceasta poate avea mai multe tipuri de constructor mai ales ddacd respectivaclas8 de excepfe este chiar 0 exceptie proprie, serisf de dum- neavoasta (paragraful 6.3), In mod obignuit sunt dou puri de constructor care pot pela: constrictorul implicit, care nu are parame, si constrictorul ‘ou un mesaj de tip String. De exempli tanga unei clase throw new TeaTootlotException (): throw new TeaTootlotException ("Ceaiul este foarte * + Fierbinte."): De obicei, se arunct cate o clasi diferits de excepfie pentru fiecare tip de ‘eroare intilnit. Avand in vedere tipurile de constructor ai clasei de excepyic, formayia despre eroare este reprezentati atat in interiorul obiectului de excepyie (cu ajutorul unui mesaj String etc), ct side tipul obiectului de exceptie (cu alte cuvinte, de numele clasei de exceptie). Uneori este necesar ca o anumiti excepfie si fie rearuncati, adicd 8 fie aruneata exact in locul in care a fost prinsA. Tati un exemplu de rearuncare a a > eateh (Exception e) “t + throw e: " Prinderea si rearuncarea aceleiasi excepyii (ca in exemplul anterior) nu are nici un sens, deoarece este ca si cum am ignora excepfia espectiv’. Situafia este diferitAins& cind tipul excepfiei prinse nu este neapsiat acelasi cu tipul excepfi rearuncate. Asemenea situatii apar freevent in aplicajile ceva mai complexe {in care o excepfie de un anumit gen este “tradusi” intro excepfie de alt gen, arcu conjinut echivalent (de exemplu, int-o aplicatie client-server, o exceptie prin care serverul anunja c& nu a putut procesa o anumita cerere a clientuui 196 (65, ARUNCAREA EXCEPTILOR este tradust de programul client into alti exceptie cares consi un mesa} hil pentu utilizator. in exemplol urmator, HyWewEXcept-ion este 0 clas excepfie propre aruncaa in cazl prinderiunei except de inrae-ieyire vty a “ Seateh (IOException ©) “ } throw new MyNewException (): "1 65.2 Clauza throws rice metodi Java trebuie fie sa prinda, fie si specifice clar toate exceptiile pe care le arunci mai departe metodelor care 6 apeleazi. Este vorba, desigur, de excepfilletratate (adied, cele care nu sunt derivate din Runt imeException, veri paragraful 6.2) care pot fi aruncate de codul din interionul metodei respec ‘Am prezentat pana acum doar cazul in care exceptiile sunt prinse si tratate in eadnul aceleasi metode, nefiind transmise mai departe. Aceasti secfiune va prezenta cea de a doua posiilitate: specificarea excepfilor care nu sunt tratate ccadnul metodei respective, fiind aruncate mai departe, pentru a fi prinse gi tratate de alte metode (cu alte cuvinte, vom invija cum se arunc’ pisica moarti ‘ograda vecinului), ‘Atunei edind decide ca o metodai si nu prindi o anumiti excepie care poate fi aruncaté de codul din interionul ei, trebuie s& precizim faptul cf metoda poate arunca la rindul ei exceptia respectiva (deci vecinii trebuie avertizali in legiturd cu posibilitatea de a se trezi cu o pisic& decedati in ogradi). Aceasti, ceringi este perfect explicabila, pentra cd specificarea excepfiilor aruneate mai eparte de metodi fine de interfaja metodei, cu alte cuvinte cei care utilizeaz’ © metodi trebuie sii cunoased precis ce excepfii aruned chiar gi in eazul in care ‘nu au la dispozitie codul sursi al metodei, pentru a putea elabora o strategie de tratare a respectivelor excep Specificarea exceptiilor aruncate de o metoda se realizeazi prin intermediul clauzei throws, utiliza in antetul metodei respective: tipReturnat numeMetoda(listaArgumente ) throws Exception! . H a 197 (65. ARUNCAREA EXCEPTHILOR 4irect, folosind instructiunea throw, precum si exceptile (netratate) aruncate de alte metode apelate, Evident, ambele tipuri de exceptii specificate in clauza ‘throws, mu trebuie si fi tratate in cadrul metodei. Dacd acest lucru se intim- pl, atunci exceptile nui mai pot fi precizate in clauza throws lati un exemplu de specificare a exceptilor care nu sunt prinse si tratate in ‘cadnal unei metode: public void drinkTea(int temp) throws TeaTooH{otException t 1) (deca temperature © prea mare Ut Cem 340) ot ‘ throw new TeaTootlotException (): 74 “ Exemplul de fay specifica faptul ci metoda drink Tea () arunci 0 ex- ceplie proprie, TeaTooHlot Exception, dact temperatura ceaiului este mai mare de 40 de grade. Datoritd acestui lucru, apelul metodei drink Tea () intr- © alti, metoda se poate realiza doar daca excepjia TeaTooHot Exception este prinsi si tratatd In cadnul acelei metode, sau daca gi acea metoda alege si anunce excepfia mai departe, specificand-o in clauza throws public void serveCustomer() c Int temperature = 45; drink Tea (temperature ): 1 catch (TeaTooHtotException exc) » 4 “ sony “public yold serveCustomer() throws TeaTooHotException a 198 63. ARUNCAREA EXCEPTILOR int temperature = 45; drinkTes (temperature): Este evident c& tn cel de-al doilea caz, excepfia va trebui prinsé gi tratati la tun moment dat, in cadrul unei metode. Deoarece este o exceptie tratati, ea nu poate fi aruncatti mai depart de fiecare metodi, iri si existe in final o metod’ ‘care si o prinda gi si o trateze. Specificarea exceptilor aruncate de o metoda nu se poate evita, acd metoda respectivi genereazii excepfii pe care nu le trateazd, deoarece compilatorul de~ tecteazi aceasti "scipare” si o raporteaza drept eroare de compilare, propu- rind dou solutit: tratarea lor in cadrul metodei sau specificarea lor in clauza throws. ‘Totusi exist o posibilitate de a "picdli" compilatorul, atunci cAnd se speci- ficd faprul c& o metodi arunci o anumita excepfie, desi acest Iucru nu se intam- pla, In aceasta situate, compilatorul obliga apelurile metodei noastre si trateze ‘exceptia sau silo specifice in clauza throws a metodei apelante, chiar dacd ‘metoda noastri nu arunc& propriu-zis exceptia respectiva, ci doar pretinde ci ‘© arunel. Acest lucru este util in momentul in care stim cd in viitor metoda noastri va fi modificati astfe! inet si arunce respectiva exceptie, deoarece nu va mai fi necesarii modificarea codului care apeleaz’i metoda, codul respectiv tratdnd excepfia in avans, inainte ca ea si fie anuneati propriu-vis de metods. O ultima observatie: mecansimul de aruncare mai departe a excepfiilor oferi ‘6 modslitate deosebit de eleganti de a trata problemele care apar in decursul ‘execufici la nivelul adecvat. De exemplu, este foarte posiil ca o metoda care citeste un flux de octefi si intilneasc’ diverse probleme, cum ar fi: fuxul nu poate fi deschis, transmiterea de date s-aintrerupt prematur etc. Totusi, metoda respectivi este de un nivel prea jos pentru a putea lua decizi in legituri cu acfiunile care trebuie intreprinse in cazul unei erori (care pot chiar diferi de la 6 situajie Ia alta), Aruncnd o excepfie, metoda noaste’ are posibilitatea de a anunja metodele de nivel mai inalt care au apelat-o de faptul cX secventa de ‘execufie nu a decurs normal, lisind in seama acestora modul in care se trateazt ‘eroarea. Programatorii cu ceva experienga in C sau Pascal vor recunoaste proba bil superioritatea acestei metode, in fafa celei in care metoda care citea dinte-un flux de date seta o variabili sau returna © anumiti valoare care descria modul in care a decurs citirea din flux (de exemplu, returna 0 daca citirea a decurs normal, | daca nu s-a putut deschide figierul, 2 dact citirea s-aintrerupt etc). 199 (66, SUGBSTH PENTRU UTILIZAREA EFICIENTK A EXCEPTIILOR 6.6 Sugest lor pentru utilizarea eficient& a except Problemele cele mai mari cu care se confrunti programatorii atunci cind utilizeazi excepfiile Java sunt ednd si ce except si arunce. Pentru prima problems, rispunsul sumar pe care un programator ar putea sie ofere, ar arita astfel: Daci o metoda intalnesteo situate anormal pe care nu o poate trata, atunci metoda respectiva ar trebui s& arunce o exceptic. Din nefericire, acest rispuns este ct se poate de ambiguv, petra c¥ ne conduce cite o atk intrebare: ce tnseamnio “sitajieanormala"? Aceasta poate fi con- siderat ntebareacheie a tratii excepilor. ‘A decide dacio anumitastuafie este anormal sau nu, rimne nso proble- imi subiectiva. Decizn neste inotdeauna evident ide aceea depinde in mare misurd si de programator. Tosi stuaia nu este chiar att de gravape cat ati tents credfi Pent a ven in ajutoral programatoritr, creator limbajult Java au considerat c& o bund regu de utilizar a excepfillor este acoea de a “evita utlzarea excepfilor pent a indica situa previibile in funcjonarea standard aunei metode", {in consecina, 0 situajie anormali este un eveniment care mu poate fi pre- ‘azut in cal une funeiondr normale a metode. Penta o mai bund intelegere 4 acestui concept, vom considera citeva exemple utile, in care se decide daca este util sau nu utilizar excepilor. Ca exemple am aes cdteva stuaiindl- nite chiar de dezvoltator limbajului Java la creare ierarici de clase oferta de platforma Java, pentni a vedea cum a fost acesta tratate (acd a fost consi- erate situa anormale gi implicit, s-a recurs la tilizareaexcepfilor, stu dat au fost considerate situa normale, previzbil) St considerim mai inti eazul metodei read () a clasei Filetnput~ stream, disponibilé in pachetul java.io. Aceastt metodé reumeazi un byte cit dinioun fax de intra specifica. Sitaia specials cu care confrunta dezvolatori limbajului Java a fst urmatoarea: cum arf tebuit si trateze aceast metodsitaja in care toate date din fluxul de intrare au fost, cite, deci sa ajuns la stigialfgiralui? Ar fi tebuit ca metoda read () si anunce o excepyie, pent c& sa ajuns la final fiserua, sv, din conta, aceasta situaje simu fie consderaté specials, ci mai degrabi una previibila? Solujaaleasi de dezvoltatoriiimbajuui ava a fost ck metoda nu trebuie si arunce o excepfe, ci doar si retumeze 0 valoare special, -1, cares indice sfarsitalisiralu. Aste, atingera ségituli sles fost consideraté dept 200 66, SUGBSTI PENTRU UTILIZAREA EFICIENTA A EXCEPTILOR 6 situajia normala, previzibilé in utilizarea metodei read (). Motivul pentru care nu a fost consideratd o situajie anormali a fost acela e& metoda obisnuiti de acciti bytes dintrun flux de intrae, este aceea de a incerea citiea lor pe lind, pin cnd este atins finalu figierului, Aldoilea caz este cel al metodei readint (),clasa DataInput Stream, din acelagi pachet java . io. In momentul in care este apelats, aceasta metoda citeste patru bytes din fuxul de intrare gi fi convertesteintraun int. In aceasta situate, creatoriilimbajului Java au ales ca metoda readint () si arunce 0 cexceptic, EOFEXcept ion, atunci cind se ajunge la sférsitul unui figier. Dow’ ‘au fost motivele pentru care aceastsituafie a fost considerati anormali: © metoda readnt () mu poate returna o valoarea special’ pentru a sem nala sfarsitul fisierului, pentru cd toate valorile pe care le-ar putea returna sunt valori intregi care ar putea exista in ace figier (cu alte cuvinte, ~1 ru ar putea fi considerat sfarsitul figierului, pentru cd ar putea exista un ‘element ~1 in cadrl fisieruli, si astfel am fi indusi in eroare, deoarece prezenja elementului ~1 in cadrul acelui fier nu inseamna obligatoriu, cf figierul a fost parcurs pana la final); © metoda readtnt () poate fi pusi in ipostaza de a putea citi doar unul, doi sau trei bytes din fluxul de intrare, si nu patru, cit ii este necesar pentru a forma un int (o variabili de tip intreg este reprezentati in Java pe 4 octet), ceea ce poate fl consideratd o situatie anormal. Datortt acestui fapt, exceptia ZOFExcept ion este definiti ca o excepfie trata, ‘motiv pentru care programatorii care utilizeaz metoda readint () sunt obligajis8 prinda aceasti exceptie sist o trateze. Alteilea exemplu se refer la interfaja java util .-Enumerat ion,im- preund cu cele dow’ metode ale sale, hasMorezlements () si nextEle- ment (). Aceastt interfa reprezinti o modalitate de a parcurge o serie de ele- ‘mente, cite unul pe rand, de la primul element panda ultimul element al serei Obyinereaunui element din serie se face cu ajutorul metodei next Element (), ‘care returneaza elementul curent din serie $i muti pozifia cursorului pe urmi- torul element, care astfel devine noul element curent, Metoda hasMorezle- ments () retumeazi o valoare boolean’, care indic& daci seria a fost parcursi ‘in Intregime sau nu s-a atins incd sfarsitul ei. Metoda hasMoreBlement's () trebuie si fie apelati de fiecare dati inaintea metodei next Element () pent a vedea daci s-aajuns la sfarsitul seriei de elemente sau nu. Aceasti abordare ne arati cl dezvoltatori limbajului Java nu au consideratatingerea sfarsitului seriei de clemente ca find o situajie anormala, ci una previzibils. Totusi, daca sfarsi- tul seriei a fost atins si este apelata metoda nextELement (), fara a apela 201 (66, SUGBSTH PENTRU UTILIZAREA EFICIENTK A EXCEPTILOR metoda hasMoreB ements () in prealabil, atunci este aruncatt o exceptie, NoSuchE1ementExcept ion, care reprezinti o excepiie netratata (subclasi aclasei Runt ime®xcept ion), aruncati mai degraba pentru aindica o eroare de programare (faptulc4 interfaja nu este utilizat& corect), decat pentru aindica sfargitulserici de elemente. ‘up’ cum se poate observa, regula general valabil& este c¥ in cazul in care situajia este previzibila (de exemplu, sfarsitul unui figier al unei serii de elemen- te, sau obfinerea unui rezultat nul la operajia de cdstare a unui element int-un sirde elemente), nu este recomandati utilizarea exceptiilor. (© altk abordare a problemei utilizati eficiente a excepyiilor este legati de modul in care metodele sunt utilizate. Si luim cazul metodei chartAt () a clasei String, din pachetul java. ang. Aceast& metod& primeste ca ;parametru un intreg si returneazA caracterul din string aflat pe pozijia indicat de parametn. Dac metoda charAt () este apelati cu parametnul 1 sau un intreg de 0 valoare mai mare deca lungimea sirului ea nu isi poate executa sarcina pentru ‘cAdatele sale de intrare sunt incorecte. lar, dac& datele de intrare sunt incorecte, nici cele de iesire (rezultatele) nu pot fi corecte, De aceea, metoda aruncii 0 ex ceplie StringIndexOutofBoundsExcept ion, care indicd faptul cl pro- _gramatorul are o eroate de programare sau nu a uilizatclasa corect, Pe de alti parte, daciidatele de intrare sunt corecte, dar dintr-un anumit mo- tiv chartAt () mu ar putea returna caracterul de pe pozifia specificat’, atunct ‘metoda ar trebui si semnaleze acest lueru arunelind o excepfie, prin care indica faptul c& sunt probleme care necesito tratare specific Prin intermediul acestei abordiri se poate trage concluzia c& excepiiile tre- buie ulilizate atunei ednd metodele nu beneficiaza de date de intrare corecte (preconditieincilcati) sau cind, desi au date de intrare corecte,totusi, din anu- ‘mite motive, nu isi pot duce la bun sfarsit executia (postconditie incdleati. Cea de a doua problema major cu care se confrunta programatori Java este Dupa ce s-a decis utilizarea excepfilor, urmatorul pas este si decidem ce tipuri de exceptii si utiliza, Avem de ales intre a arunca exceptiiinstange ale clasei Throwable sau ale unei subclase a acesteia. Pe de alti parte, se pot arunca excepfi predefinite de platforma Java (existente in Java API, sau putem ‘rea propria ierarhie de except Prima sugestie in alegerea tipului de exceptii este aceea de a arunca in- totdeauna excepril (subclase ale clasei Except ion) si nu erori (subclase ale clasei Error). Motivul este cl Error are scopul de a semnala probleme com- plexe, delicate ale sistemului unde este preferabil si nu ne biigim nasul ‘A doua sugestie este legatt de modul de utilizare a excepiiilortratate (checked 202 66, SUGBSTI PENTRU UTILIZAREA EFICIENTA A EXCEPTILOR ‘exceptions) ia celor netratate (unchecked exceptions), Dupii cum s-a obser- vat dea lungul acestui capitol, aruncarea in cadrul unei metode a unei exce; tratate, forjeazai codul care apeleaz metoda respectiva si trateze acea exceptic. Pe de alti parte, aruncarea in cadrul unei metode a uni except ‘ceptii runtime), nu oblig’ codul care apeleazi metoda respectiva si trateze acea ‘excepfic, lisind la latitudinea programatorului decizia de a prinde sau nu ex- ‘ceptia respectiva. Sugestia in aceast situa este e8, daca suntefi de parere cl except tre- buie obligatoriu tratata de utilizatorul codului dumneavoastra, atunci aruncaji ‘excep tratate fn general, excepfile care indie o ulizare improprie a metodelor unci clase (0 eroare de programare) sunt excepfi neratate. Un exemplu potr tte el anterior in care metoda chart () aronci excepfia StringZndex- OutOfBoundsexception. Daci metoda chart () este apelai cu argu- mentul -2, ea arunci excepie prin care semnaleaza cX nu a fost utlizatt corect (nu exist indicele —1 intra sir de clemente). Pe de alté part, ex- cemplul metodei readtnt () din clasa DatainputStream gi al exceptici EOFExcept ion est ui pentn a ilstaslegerenexcepilortratate, Deoarsce cexceptia E0FExcept ion indiedo eroare care a survenit in momentl citi din figier, ma poate fi vorba deo uiizare greta casei DataTnputStrean, Excepfia semnaleazi ci, desi clasa a fost ulilizaté corse, totusi metoda mu reugit si ii indeplineaschfincfionalititea, ccea ce repreints sitale anor- mali, motiv penta care programatori care uilizeazi aceasti metods snt obi aati si trate cazul de exceptie Cea de-a teia $i ultima sugestie este aceea de a inlocui clasele de excepfii predefinite de platforma Java cu propriile clase de excep, atunci end consi- ‘derai cl ar fi mai explicit astfel. Putej realiza acest lueeu dacs prindeyi excepyia predefiniti Java, si, In codul de tratare a exceptiei respective, aruncali propria ‘dummneavoastri excepyie. Ulilizarea excepyiilorigi are propril ei pret din punct de vedere al resurselor utilizate. Datoriti stivei de apel (call stack), creat de masina virtual JVM pen- tu a refine ordinea in care metodele au fost apelate, oprirea brusci din execusic ‘unei metode (in caz de excepfie) este mult mai costisitoare decat 0 execujie fir incidente a metodei respective, deoarece magina virtual consum’ resurse ‘cdutiind in stiva de apel, metoda care confine seeventa de cod ce trateaza res- pectiva exceptie. Din acest motiv, excepyiile rebuie utilizate ponderat, mai ales in metodele care se apeleaza foarte frecvent si a ciror viteza de executie este cesengial. 203 (62. AVANTAJELE UTILEZARI EXCEPTUILOR. CONCLU2H 6.7 Avantajele utiliza excepfiilor. Conclu: Existenja unui mecanism de tratare a erorilor este una dintre principalele modalitigi de a creste robustefea unei aplicati. Tratarea erorilor este un prin- cipiu fundamental pentru orice aplicatie, in special in Java, unde un fel foarte importanteste acela de a crea componente de aplicajii care vor fi utlizate de alfi programatori. Pentru a asigura dezvoltarea unei aplicaji profesionale, fiecare dintre aceste componente trebuie si fle robust, Exceptiile ofer multe avantaje programatorilor. in primul rind, ele separa codul care trateaza erorile de codul care funcfioneazi normal, Codul suspect de 4 se executa cu eroare (chiar dacit aceasta eroare poate apare doar in 0, 001% din cazuri) este incadratintr-un bloc try pentra a fijinut sub observatie. Chiar ac’ ulilizarea exceptiilor vi poate ajuta SX face{i codul mai lizibil, prin sepa- ratea codului de tratare a erorilor de cel normal, totus, utilizarea inadecvatd a lor produce un cod dificil de citit si injeles. Pe de alti parte, mecanismul Java de tratare a erorilor permite propagarea erorii prin aruncarea mai departe a ero- rilor prinse, obligind alti metoda si le trateze. Nu in ultimul rand, verificarea de citre compilatora existenjei codului de tatare a unei excepfii trata, este un prim pas spre a avea un cod stabil si robust. Din aceste motive este indicat ea pentnu fiecare aplicajie si se dezvolte o strategie de tratare a exceptilor. De asemenea, excepiiile nu trebuie si fie con- siderate ca un adaos la o aplicafie, ci ca o parte integranti a acesteia, iar pentru 8 realiza acest lucrueste necesar-a strategia de ratare a exceptilor si fie adoptati in impul fazei de proiectare a aplicajii, si nu in faza de implementare. Rezumat Capitolul de faja a prezentat modalitatea exceptie in cadrul unei aplicafii Excepiiile sunt folosite pentru a semnala situayii de eroare. © excepie este generati de clauza throw si se propagi pan este prinsi si tratati de un bloc catch, asociat cu un bloc try. Pe de alti parte, metodele specific in cadrul unei liste throws excepyiile tratate pe care le arunc’. Capitolul urmator prezinta pe scurt sistemul de intrarefiesire in limbajul Java ccare Java trateaza situatiile de Nofiuni fundamentale catch: bloc de instrucjiuni utilizat pentru tratarea unei except 204 62. AVANTAJELE UTILIZARILEXCEPTILOR. CONCLUZH excepfie runtime: excepfie netratat care nu necesita si fe prins gi rata (ex. Nul1PointerBxception, IndexOutOfBoundsExcept ion). ‘excepfie tratatii: exceptie care trebuie prins’ sau propagata explicit intro clauzi throws. finaly: bloc de instructiuni care se executd indiferent de rezultatul exe> ‘cutiei blocului try-catch. Nul1PointerException: tip de exceptie generati de incercarea de @ apela un atribut sau o metoda pe o refering’ nut. ‘throw: instrucfiune utilizaté pentru a arunca 0 exceptic. ‘throws: indica faptul c& o metoda poate propaga o exceptic. ‘try: cuprinde codul suspect, care ar putea genera o excep Erori frecvente 1. Excepyiiletratate trebuie si fe in mod obligatoriu prinse sau propagate in ‘mod explicit prin intermediul clauzei throws. 2. Desi este tentant (de dragul simplitiii) si scriem clauze catch vide, aceasta face ca programul si fie foarte dificil de depanat, deoarece ex- le sunt prinse fri ase semnala deloc acest luc. Pe scurt 1, Deseriegi mecanismul de funcjionare a excepyiilor in limbajul Java, 2. Care except trebuie tratate obligatoriu si care mu? in practic’ 1. Creafi o metodimain () care arunci un obiect de tip Except ionin in- teriorul unui bloc t'y. Furnizaji constructorului obiectului Exception, ‘un mesaj de tip St ing. Prindei excepyia in cadrul unei clauze catch si afisasi mesajul de tip String. Adiugajio clauza finally in care si tipaciji un mesaj pentru a verifica faptul c& aji trecut pe acolo, 2. Creati oclast proprie de excepfi, aseminitoare lui TeaTooHot Excep- ‘ton din paragraful 6.3, Adaugaj clasei un constuctor cu un parametru de tip String care refine parametrul intr-un atribut al clasei.. Scriegi 205 (62. AVANTAJELE UTILEZARI EXCEPTUILOR. CONCLU2H ‘© motoda care afigeaz String-ul stocat, Exersayi noua clasi creat folosind un bloc try-cat ch, 3. Serie o clas cu 0 metoda care si arunce o exceptie de tpal eee de- serise la exercjiul anterior. Incercaji si 0 compa fra a preciza ex- cepjia in claiza throws, Adiugajiapoi clauza throws adecvata gi apa metoda in cadral unei claize try—catch 4, Declara o refering si niializat-o eu nu, Apetat apot o metodk pe refering espectva, pentn a verificafapole8 ve objine tiv Posnter- Exception. Ineadrfi apoi apeul inten bloe try-catch pentna a prinde except, 5. Scriefi o secventi de cod care si genereze si si prindi 0 exceptie de lipul ArrayIndexOutOfBounds=xception sau de tipul String- IndexOutOfBoundsExcept ion. 6. Defini clasi eu douit metode, £() gi g()- fn metoda £() arunca ‘© excepfie de un tip definit de dumneavoasiri. in metoda g() apelai metoda £ (), prindefiexcepiiaaruncat& de £ () i aruncaji mai departe 0 ‘excepfe de tip difer, Teta codul in metoda main () a clase. 7, Definigi o metoda care aruncé (in clauza theows) mai multe tipuri de ‘excepfii definite de dumneavoastr’. Apelaji apoi metoda si prinde}i toate ‘excepiille aruncate folosind o singura clauzi catch. Modificasi apoi programul astfel incat clauza catch sa prinda doar aceste tipuri de ex- cept. 8, Pentru exemplul cu clasa Shape din capitolul anterior, modificati meto- dele readShape() simain() astfel incat ele si arunce gi si prinda ‘except (in loc st creeze un cere de razit 0) atunci cand se observ 0 ceroare la citire. 9, in multe situafii o metoda care arunci o exceptic este reapelata pana ciind ‘execufia ei decurge normal sau s-a atins un numar maxim de incerciti ‘Creaji un exemplu care si simuleze acest comportament, prin apelarea uunei metode in cadrul unui cicla whi le, eare cicleaza pnd cand nu se ‘mai aruneé nici o exceptie. 206 7. Intrare si iesire (Java I/O) “Poi simi spui te rog, pe unde shies de aici "aceasta depinde in mare misuri de unde vrei si mere", spuse pisica "Nu prea Imi past unde.”,spuse Alice. “Atunci nu conteazi pe ce drum jer ‘minunilor {in capitolul anterior am prezentat excepfile Java si modalitatea in care se trateaz situaiile de eroare aparute in cadrul unei aplicaii. in capitolul de fai vom parcurge pe scurtsistemul Java de intrare-iesire Vom afla detalii despre: # Cum este siructurat sistemul Java de intrae si iegire (VO); © Care sunt modalititile de a citiserie date intr-o aplicatie Java; ‘ Cum sunt utilizate pachetele de resurse pentni a simplifica citirea datelor de intrare int-un program Java, 7.1 Preliminarii Intrarea 51 iesirea in Java se realizeazi cu ajutorul claselor din pachetul pre- definit java.io. Din acest motiy, orice program care foloseste rutinele de intrarefegire trebuie si cuprind’ instrucyiunea 207 172 ORERATILDE DAZA PE FLUXURI(STREAMURI) enter Biblioteca Java de intrareiesir est extrem de soisticaté sare un numir foarte mare de opiun. fn cadral acestsi capitol vom examina doar elementele de baz refertonre ln inteare gi egre, concentrindu-ne tn ftregime astra ope- tailor de intrare-egceformatate (au vom vorbi despre opera de intrar-iyire binare) ‘Desi pracicd programele Java ii preiau datele de intrare din fsiere sau chia rin Internet, penta cei care inva acest imbaj este uneori mai convenabil si prea date dela tasttur, aga cum obignuia in C sau Paseal. Vom aria in Paragrafele care urmeari cum se pot prelua datele de a tasttur si ct de pine modifica sunt necesare penta a prelua aceleasi date din ger 7.2. Operatii de bazi pe fluxuri (stream-uri) Java oer tei uri predefnite per operat VO standan system. 1n Gatearea standard; «# system. out (eres standard); + system. ers (thnul de ero Asa cum am aritat deja, metodele print si print1n sunt folosite pentru afigarea formatata, Orice fel de obiect poate fi convert la o forma tiparibila, folosind metoda toString}; in multe cxzuri, acest luca este realizat au- tomat. Spre deosebire de C si C++ care dispun de un numar enorm de opti 4e formatare, afisarea in Java se face exclusiv prin concatenare de String-uri, ‘iri nici o formatare (© modalitate simpli de a realiza citiea este aceea de a citi o singuri linie Intr-un obiect de tip String folosind metoda readLine(). readLine() preia caraetere de la intrare pani cind intilneste un terminator de Tinie sau sfirgit de figier. Metoda retumeazi caracterelecitite (din care extrage termina- tonul de linie) ca un String nou construit. Pentru a citi date de la tastatur’ folosind readLine() trebuie si construim un obiect BufferedReader dine-un obiect Input StreamReader care la randul su este construit din System. in. Acest lucr a fost ilustrat in capitolul 3, Listing 3.2 Dac primul caracter cit este BOF, atunci metoda readLine () retuneaz’t ‘nu1, jar dac apare o eroare la citire, se genereazd o excepie de tipul LOEx- ception. In cazul in care girul citit nu poate fi convertit lao valoare intreagi, se genereazi o exceplie Number F ormatExcept ion, 208 7.3, Obiectul StringTokenizer Obiectul StringTokenizer ne permite si separim elementele lexicale distinete din cadrul unui string. S& ne reamintim cl pentru a citi o valoare primitiva, cum ar fi int, foloseam readLine() pentru a prelua linia ca pe uun String gi apoi aplicam metoda parsetnt () pentru a convertistringul la tipul primitiv. {in multe situayii avem mai multe elemente pe aceeasi lie, Sa presupunem, de exemplu, c& fiecare linie are doua valori intregi. Putem accesa fiecare din- tre aceste dou valor, utilizand clasa StringTokenizer pentru a separa ‘String-ul in elemente lexicale (engl. token), Pentnu a putea folosi obiecte ale clasei Str ingTokenizer se foloseste directiva Import java. util. StringTokenizer Folosirea obiectului StringTolenizer este exemplificati in programul din Listing 7.1. Obiectul Str ingTokenizer este construit in linia 19 prin furizarea obiectului String reprezentindliniacititi. Apelul metodei count Tokens () din linia 20 ne va da num: 1 de cuvinte cite (elemente lexical). Metoda next Token () intoarce urmitonsl cuvant necitit ea pe un String. Aceasti ultima metodi genereazi o excepjie NoSuchElementExcept ion ddaci nu existi nici un cuvant rimas, dar aceasta este o exceptie de execusiestan- dard gi nu trebuie neapirat prins&. La linile 26 gi 27 folosim next Token () urmati de parseZnt () pentru a obfine un int. Toate erorile sunt prinse in blocul catch. Implicit, Java consider spayiul, caracterul 1ab sau linia now’ drept delimi- {ator al elementelor lexicale, dar obiectele de tip StringTokenizer pot fi construite gi in asa fel incat si recunoascd si alte caractere drept delimitatori, Li \Tiprogram pentru exemplificarea clasel s//StringTokenizer. Programul civeste doua numere aflare pe ing 7.1: Program demonstrativ pentru clasa StringTokenizer lowe: javaluuds public class TokenizerTest a public state vold main(String [] args) wd BufferedReader in = new BufferedReader( mew InputStreamReader (System. in): 209 14 FSIERE SECVENTIALE. s System.out.printin("Introduceti 2 ne. pe linie:* “uy an e String s = in readLine (): % SteingTokenizer. st = new S > In (st countTokens 0) t= 2) a i 2 System. out. printin(*Numar invalid de * + 2 “argumente!"): ringTokenizer(s) e ) * Int x = Integer. parselat st -nextToken ()) > int y = Integer, parselat (st snextToken ())+ % System. out.printin ("Maximul este: + > Matheman (x. 99) % eateh (Exception e) > System. out, printin (2): wy a 7.4. Fisiere secventiale Una dintre regulile fundamentale in Java este accea ci ceea ce se poate face entra operajii VO de la terminal se poate face si pentns operafii VO din figiere. Pentru a lucra cu fisiere, obiectul BufferedReader nu se construieste pe bava unui InputStreamReader. Vom folosi in schimb un obiect de tip FileReader care va fi construit pe baza unui nume de figier. Un exemplu pentru ilustrarea acestor idei este prezentat in Listing 7.2. Acest program listeazX conjinutulfisierelor text care sunt precizate ca parametti in linie de comand’. Funcjia main () parcurge pur si simplu argumentele din linia de comanda, apelind metoda List File () pentru fiecare argument. in metoda List Pile() construim obiectul de tip FileReader Ia linia 26 si folosim pe acesta pentru construitea obiectului de tip BufferedReader jurmatoare, Din acest moment, citirea este identica cu cea de la tastatur ‘Dupaice am incheiat citirea din figier, tebuie si Inchidem fisierul, altfel s-ar putea si nu mai putem deschide alte steam-usi (si atingem limita maxima de stream-uri care pot fi deschise). Nu este indicat si facem acest lucra in primul bloc ty, deoarece o excepfie ar putea genera pirisirea prematurd a blocului si fisicral nu ar fi inchis. Din acest moti, fisierul este inchis dupa secvenja, try/cateh. 210 74, RSLERE SECVENTIALE ilar cu citrea formatat, Scrierea formatati in fisiere est si Listing 7.2: Program care listeazii continutul unui figier Tiprogram penira afisarea continutului fisierelor Wale caror mme sunt preeizate in linia de comanda Import java.io. pablic class Lister { ablic state vold main(String {] ergs) ‘ Af (args length | Sem out pinta Niel oy fsier presiat!: ° for (int i = 0; 1 < args.length; +44) fl LstFite (args(i})s ) ) public statle yold listFile(String fileName) System. out. printin ("NUE FISIER: " + fileName): try t FileReader file = new FileReader (fileName BufferedReader in = new BufferedReader file) String s: while (5 i System out. printin (s) 1 ) catch (Exception ©) fi System -out. printin (e) in. readLine()) != null) try i i Cin t= 1 ) catch (IOException ©) (H/ignora exceptia } in. close (0s au 113, UTILZAREA COLECTILOR DE RESURSE @ESOURCE BUNDLES) 7.5 Utilizarea colectiilor de resurse (resource bun- dles) Vom prezenta acum si o alti modalitate de a stoca si accesa date, in care se foloseste o structurare a datelor Ia un nivel superior: colecfile de resurse (resource bundles). ‘Scopul pentau care colecfile de resurse au fost implementate de creatorii Timbajului Java, nu a fost acela de a le folosi pentru citiea de date, ci pentru 1 realiza intemajionalizarea aplicapilor, eu alte cuvinte pentru a permite tra- ducerea interfeei unei aplicafi dintr-o limba in alta, intr-un mod foarte simplu, Utiizarea lora fost insi extinsd de programatori gi penta a stoca gi citi date fnte- un format mai organizat, superior orientari pe octeti a fluxusilor de date. Vom prezenta in continuare un exemplu simplu de utilizare a colecjiilor de resurse pentru a extrage informarii dinte-un fisier de proprietaji, Anexa D prezinta in detaliu modul in care se utilizeaza colectiile de resurse si in alte direct 7.5.1 Utilizarea fisierelor de proprietafi pentru citirea datelor Colecile de resurse pot fi eprezentate sub mai multe forme in Java. Anexa D va sti la dispovitie pentra limuriri in aceasta privinja. Ca exempla, am ales pentru reprezentarea colecfilor de resurse varianta figierelor de proprieti Figierele de proprietii sunt simple fisiere text, cu extensia .properties. Tat un exemplu: #£isierul de proprietati pentru programul Human. java age=14 height=1.70 Dupa cum se poate observa, fisierul de proprietiji este format din perechi de tipul cheie/valoare. Cheia este de partea stingi a semnului egal, ar valoarea este de partea dreapti. De exemplu, age este cheia care corespunde valosii 14 Analog, putem spune ci 14 este valoarea care corespunde cheii age. Cheia este arbitrar. Am fi putut denumi cheia age altfel, de exemplu myaige sau a, ‘Odata definita ins’, cheia nu trebuie schimbat’ pentru ci ea este referitin codul sursi, Pe de alta parte, valoarea asociata cheii poate fi schimbata far probleme. 212 113, UTILIZAREA COLECTIILOR DE RESURSE (RESOURCE BUNDLES) De asemenea, se remarca faptul ci semnul # este folosit pentru comentarea unei linii din cadral fisierului de proprietii ‘Si consideraim ci figierul de proprietiti prezentat mai sus este salvat pe disc fisieru] cu numele humanProp. properties. Evident, putefi schimba acest nume cu unul la alegerea dumneavoastri. Programul Java din Listing 73 prezinti o modalitate de utilizare a acestui pachet de resurse (pentru ex ‘cutie corecti,salvaji acest fisier cu numele Human . java in acelasi director cu fisierul humanProp. properties). Listing 7.3: Program de test pentru fisiere de proprietigi Import java-uuil public class Human t + public static void main(String eras (1) _ ot : wy : fl : ResourceBundle rh = Resourcelbundie . getBundle( ” ‘humanProp" ): E String s1 = eb. getString ("age"): Ee System out. printin (st): " String s2 = eb. getString ("height"): “ System out. printin(s2): * ) if ceateh (Exception ¢) a fi > System out. printin "EXCEPTION: * + c. getMessage ()): 5 ) a ” Uilizareafisieelor de propricti este, dupa cum se vede si in exemplal precendent, destul de simpli. Metoda getBundie () realizeaz accesul la fisieral hunanProp.praperties. Se observa faptulc& mu este necesard extensia .propert ies in apelul metodei ‘Accesul la vaorile cheilor se face prin metoda get string (). Trebuie refinut fatal ci toate valorile care sunt preluae din fsjerele properties sunt detipul Sting, De aceea cl trebuie converte cite ipurile lor. in cazal rosin, valoarea cheii age trebuie convertité la int, iar cea a cheii height. la Float sau double. Penta a pisteasimplitatea programulu, am ales si niu mai convertim aceste valor, ci doar le afm pentru a testa valoarea lor. Rezultatelafgii exe 213 113, UTILZAREA COLECTILOR DE RESURSE @ESOURCE BUNDLES) 14 1.70 Aceasti modalitate de organizare si citire a datelor este deosebit de utili penta pista date a cor organizare logici este de forma cheie~valoare, cum ar fi de exempla stocareaopfiuniloruilizatoruluiuneisplcai. fn eazal unui editor de texte scrs in Java igieal de proprietji ar putea stoca prefrinele utizatorula reteritoae Ia dimensiunea fontului, culos, directonul de pornire ote Rezumat Ceea ce am prezentat in acest capitol a constituit o prezentare sumari, dar suficient& pentru a putea merge mai departe, a sistemului de intrare-iesire ex- istent in Java, Au fost prezentate luxurile de intrarefiesire, clasa St ingTo- kenizer, fisierele secvenfiale si colecile de resurse. Degi introduse pentru a permite internationalizarea aplicaiilor (vezi anexa dedicatd acestei probleme), ‘am vizut cum pot fi uilizate colectile de resurse pentru a prelua date din figiere de proprietii Nofiuni fundamentale ‘argument in linie de comand: paramettu scris in linia de comand in care se realizeazi execujia programului respectiv. Acest parametru poate fi folositin ccadrul funcjiei mai a aplicayei ulate BufferedReader: clasi Java predefinit separate a datelor de intrare. colectie de resurse: muljime de proprietati care au asociate anumite valori Cunoscuti si sub numele de pachet de resurse. FileReader: clasi utilizata pentru lucrul cu fisiere. fisiere de proprietifi: fisiere text avand extensia .properties, cu un cconginut special, format din perechi de tipul proprietate=valoare, sto cate fte una pe Tinie StringTokenizer: clast utilizati pentru a delimita cuvintele existente {n cadrul unei propoziji. Cuvintele sunt despite prin separator System.out, System.in, System.err: fluxurile standard de ie- sire, intrare, eroare pentru operaji de citie-seriere 214 utiizat& pentru citirea pe linit 113, UTILIZAREA COLECTIILOR DE RESURSE (RESOURCE BUNDLES) Erori freevente 1. Fisierele de proprietiji trebuie si iba extensia .propert Les. Exereifii 1. Scriejiun program cate afgeaz numirul de caractere, cuvinte, linii pen- nu fisiete precizate in linie de comands. 2. Implementai un program care realizeaza copierea unui fisier dintr-o lo- cajie in alta 8. Fire de executie ‘Timpul este modalitatea prin care natura are grij si nu se produc total simoltan, ‘Autor anonim Programarea concurenti reprezint pentru mulji programatori Java un con- ccept neobisnuit, care necesiti timp pentru a fl asimilat. Efortul necesar pen- tru tranzijia de la programarea neconcurenti la programarea concurenta este aseminator cu cel pentru tranzifia de Ia programarea procedurali Ia progra- ‘marea orientat& pe obiecte: o tranzitie dificil’, frustrant& uneori dar, in final, efortul este recompensat pe deplin, Dact la prima parcurgere nu ingelegeyi a- rnumite seevenfe din acest capitol, pentru a vi usura sufletul dai vina pe slaba inspirajie a autorilor, Hisaji ceva timp pentru ca informaile s& se asimileze gi Incercaj si ulajiexemplele, dupa care reluafi secvenja care v-a creat dificult {in acest capitol vom prezents: # Ceeste un fir de executie: © Cum se ereeaza aplicatii care ruleazai pe mai mult fire de executi + Cum se eviti inconsistenja la concureni folosind metode sineronizate gi instructiunea synchronized; # Cum funcjioneazii monitoarele fn Java; * Cum se coordoneazi frele de execute folosind metodele wait () sino~ tify 216 {iL CB ESTE UN FR DEEXECUTIE? 8.1 Ce este un fir de executie? Firele de execuje (engl. treads) permit unui program si execute mai multe pari din el tnsusi in acelagi imp. De exemplu,o parte a programului poate st realizeze 0 conexiune la un server de internet sisi descarce nigte date, tn timp ce cealaltd parte a programulu afigeaz8fereatra principal i meni apicafiet pentru a putea interacfona fn acest timp cu usilizatorul, Un alt exemplu clas de utilizare a firelor de execujie il constitu un browser de Web care vi per= mite s& descareati un numar nedefinit de figiere (fecare operatic de descarcare reprezintd un fir de execate), timp in care pute st navigatinestingherii prin alte pagini (pe un alt fir de executie). Firele de execusie sunt 0 invengierelativ recent in lume is dost procesele, srorle lor mai mar, sunt foloste deja de cfteva deceni, Firele de executie sunt aseminitoare cu procesele, in sensulc& pot fi executate indepen- dent si simultan, dar difer8 prin faptu c& nu implic8 un consum de resurse att de mare. Cei care afi programat in C sau C++ v8 amintji probabil faptul cf prin comanda fork se putea crea un nou proces. Un proces atfl creat este 0 copie exactd a procesulii original avind aceleasi variable, cod etc, Copierea tuluror acestor date face ea aceasté comands si fe costisitoare ca timp de ex- ecutie si resurse folosite. in timp ce nuleaza, procesele generate prin fork sunt complet independente de procesul care le-a crea, ele putindu-si chiar modifica ‘arabilele fila afectaprocesul print Spre deoscbire de procese,frele de exeeusie nu fac o copie a intregult proces pirinte, ci pur gi simpli ruleazo alt seevengi de cod tn acelagi timp. Aceasta inseamnt ci free de execufie pot porite rapid, deoarece ele nu necesit copierea de date de la procesulpirinte. In consecinf, rele de execufie ‘vor partaja fare ele dale procesuluiclrua fi aparfin, Ele vor putea sere sau cit variable pe care oricae alt ir de executie Te poate accesa. Din acest motiv, comunicarea tate firle de execuje este mai facili, dar poate conduce gi la situaia in eare mai multe fre de execufie modifi aceleasi date fn acelagi timp, conferind rezultate imprevizbil Firele de execujie permit o mai bund utlizare a resuselor calculator in siwaia fn care magina vieuald Java (SVM) ruleazi pe un sistem multiproce- sor, free de execufie din cadrul apicajei pot si ruleze pe procesoare diferite, realizind astel un paralelism real. Am aritat deja c& exist avantaje efective ale uilizi frelor de execuje si pe sistemele cu un singur procesor. Folosirea Jor permite scrierea de programe mai simple si mai usor de ineles. Un fir de executie poate sX execute o secven{t de cod care realizeaz8 o operaie simp, 1isind restul munetialtor fie de execuje fn rezumat,putem spune c& un proces este un program de sine stititor, care 217 £2. FIRE DEEXECUTIEINAVA dispune de propriul lui spajiu de adrese. Un sistem de operare multitasking este capabil si ruleze mai multe procese (programe) in acelasi timp, oferindu-le periodic un anumit numa de cicluri procesor, lisind astfe! impresia c& fiecare proces se executi de unul singur. Un fir de execufie (thread) reprezint un singur flux de execujie din cadnul procesului, Astfl, un singur proces poate sa comin ‘mai multe fire de execujie care se executi in mod concurent 8.2 Fire de executie in Java Speciticailelimbajului Java defines free de exceujie (thread-urile) ca fcind parte din bibliotecile Java standard (pachetele java..*). Fecare im- plementare a imbajuui Java trebuie si famizeze biblioteile standard, deci im- plicit sh supore i fie de execute. fn consecings, cei care dezvoltéaplicatt Java po intotdeauna si se bazeze pe fptul ci firele de execuie vor prezente pe orice platforma va ula programol. Mai mult, toate bibiotecie standard Java fie sunt thread-safe (adic8 sunt fable in cazal utiliza lo simultane de cate ‘mai mule fre de execute) sau, dack mu, au macar un comportament bine definit fn aceast sitajie. De exemplo, se sie c& clasa Vect.or este thread-safe, deci elementele dintr-un vector pot f modifica de cate mai mule fire de execuyie simulta, fara se pide consistenjadatelor. Clsa ArrayList este echiva- lental clasei Vector care na este thread-safe, dar are avantajl de a fi mai rapid’. 8.2.1 Crearea firelor de executie fn Java existi dud variant pent a crea fire de execu: fe se deriveari dinclasa Thread, i se implementeaz4interfaja Runnable. Ambele variate conduc la acelasirezulat. Dad se implementeaziinerfja Rune, putem convert clase deja exstente la fie de execufie fri a fi nevoie si modificim clasce din care acestea sunt derivate (acesa este practic singurulavantajadus deimplementareainterftei Runnabte). Derivarea din clasa Thread ‘Coa mai simpli modalitate de a creaun fir de executie este si extindem clasa ‘Thread, care confine tot codul necesar pentru a crea si rula fire de execute. Cea mai importants metodé pentru clasa Thread este run (). Prin redefinirea acestei metode se precizeaza insiructiunile care trebuie executate de firul de 218 82. FIRE DEEXECUTIEINAVA Listing 8.1: Exemplu simplu de fire de execujie create prin derivarea din clasa Thread \ public class SimpleThread extends Thread private Int countDowa private statle Int threadCount Private Int threadNumber public SimpleThread() t threadNumber = +4threadCount s System-out.printin("Creez firul ar. * + threadNumber ): so hi public void ran() ud Ss white(tee) so System-out.printin ("Fir nr. * + threadNumber + 7(" + " countDown +")")5 '% —1f(—-countDown == 0) » ) >) “od peblic static void main( Si t for(int = 0; F< 3; 149) fi mew SimpleThread (). start Qs ny hv System. out. printin("Firele de executie au fost pornite."); > 20) ares) ‘executie. Practic, metoda run () fumnizeazii codul care va fi executat in paralel ‘cu codul celorlalte fire de execufie din cadrul programulu. Programul din Listing 8.1 creeaza3 fre de execute, fiecare fir avand asociat uun numar unic, generat cu ajutorul variable statice threadCount. Metoda run() este redefinité fn linile 13-24 pentra a seddea valoarea unui contor (variabila count Down) la fiecare execufie a ciclului while pan’ cand va- Joarea contorului ajunge la 0, moment in care metoda run () se incheie, iar firul de executie este terminat. 219 £2. FIRE DEEXECUTIEINAVA fn marea majoritate a cazurilor,instrutivnile din metoda run () sunt eu prinse into insrutiune de cilare care se executi pnd cndfial de execujie 1m mai este necesr (in cazal nostra, pina cind contorl ajunge la). fn metoda main () line 26-2, se crear si se pomese 3 ie de execute Metoda start () din clasa Thread iniializeaza fl de executie dupa care ‘fi apeleaz’ metoda run(). Agadar, pagii pentru crearea unui fir de executic sunt se apeleari constructor pentn a crea obiectil, apo metoda st.az* () configureazi ful de execufe gi apeleazé metoda run (). Daci au se apeleazi metoda start () (lier care poate fi facut chiar si fn constrictor) fra de execuyie nu va fi porntniciodah Iesiea fiat de programul din Listing 8.1 (care difer de lao execuie la alta) ese creez firul ar. 1 Creez firul nr. 2 Fir de executie nr. 1(5) Fir de executie nr. 1(4) Fir de executie nr. 1(3) Fir de executie nr. 1(2) creez firul nr. 3 Fir de executie nr. 1(1) Firele de executie au fost pornite. Fir de executie nr. 3(5) Fir de executie nr. 3(4) Fir de executie nr. 3(3) Fir de executie nr. 2(5) Fir de executie nr. 3(2) Fir de executie nr. 3(1) Fir de executie nr. 2(4) Fir de executie nr. 2(3) Fir de executie nr. 2(2) Fir de executie nr. 2(1) Observati ed fiele de execufie nu au fost executate in ordinea in eare au fost create, De fapt, ordinea in care procesorul ruleaza firele de execusie este nede- terminati, cu exceptia situafiei in care se foloseste metoda set Priority () pentru a modifica priortatea de execusie a unui thread, Un alt lucru demn de remarcat este c& la crearea unui fir de executie in linia 30, metoda main () nu refine nici o referin(a catre obiectele nou create. Un obiect Java obignuit ar fi in aceasta situajie disponibil pentru colectorul de 20 82. FIRE DEEXECUTIEINAVA gunoaie (care, dact tot veni vorba, ruleaz& si el pe un fir de execute separat), darnu siun fir de executie. Fiecare fir de execusie se inregistreaza pe el insusi in ‘cadrul masinii vituale, deci exista undeva o refering§ cate el, astfel incat colec- torul de gunoaie nu va putea si il distruga atat timp eft firul este in executie. Implementarea interfefei Runnable ‘Ajunsi cu lectura in acest punct al cri ar trebui si fii familiarizai cu not uunea de interfafi, prezentatiin capitolul 5. Implementarea interfejei Runnable reprezinti o modalitate eleganti prin care putem face ca orice clast care o im- plementeaza si ruleze pe un fir de execusie distinet. lati codul pentru interfaja Runnable: public Interface Runnable extends Object 5 public abstract vold run() : a Agadar interfaja Runnable este foarte simpli, inst deosebit de puternic’, ‘Toate clasele care implementeazs aceasta interfaga trebuie, desiguer, s& imple- menteze metoda run (). Este interesant de remarcat faptul ci noul fir de exe- ‘cujie se va crea tot cu ajutorul clasei Thread, care oferiiun constructor avand ‘ca parametmu o instanja Runnable. Clasa Taeead va executa in aceasta situ- ajie metoda run () a parametrului in cadrul metodei sale main (). Firul de ‘execufie se va incheia in momentul in care metoda run () se incheie. Astfel, aceasta interfafi foarte simpli permite ca oricare clas& care o implementeaza si ruleze pe un fir de execusie separa. Ajunsi in acest punt, v-ali pus probabil intrebarea: de ce este necesar si avem si clasa Thread i interfaja Runnable? Exist& situaji in care este ‘mai adecvat si se implementeze interfaja Runnable gi situayii in care este de preferat si se extinda clas Thread, Crearea unui fir de execujie prin imple- ‘mentarea interfejei Runnable este mai flexibil8, deoarece poate fi intotdeauna, utiizatd, Nu veji putea fntotdeauna sé extindesi clasa Thread. Adevirata pu- tere a interfejei Runnable iese in evidensa in momentul in care avefi o clas’ care trebuie si extind o alti clas pentru a mosteni un anumit gen de functi- onalitate. fn acelagi timp, ati dori ca acea clasa si ruleze pe un fir de execujie separat, Aici este cazul si folositi Runnable. ‘Odati ce avesio clasi care implementeaz Runnable gi defineste o metod’ run (), suntefi pregitifi pentru a crea un fir de execufie. $i in aceasti situatie va trebui si instangiaji clasa Thread, Fiecare fir de execusie in Javaeste asociat ‘cu o instanja a clasei Thread, chiar dacd se utilizeaza interfaja Runnable. t deja, clasa Thread ofera un constructor care primeste 221 £83, ACCESUL CONCURENT LA RESURSE a parametru o instangi Runnable. La instanjierea clasei Thread, cu acest constructor, metoda run() a clasei Thread apeleaza pur gi simplu metoda run () a clasei primita ca parametru, Puteji verifica acest lucra cu usurinj, cexecutind urmitorul program: + public 6 TestRunnable Implements Runnable 1 public statie void main(String [} args) oe 5 new Thread ( new TestRuanable () ). start (): oo Public void run() i new Exception (). printStackTrace ()s Em em Program de mai sus reprezini un exemplu simplu de creare a uni fir de execute prin implementarea intefefei Runnable. La lini 1 declarim fatal c¥ clas noastrsimplementeaz& interfaja Runnable. fn linile 7-11 defnim metoda ra () care mu face decit si apeleze metoda print StackTeace () a clasei Exception, dupa care se incheie si, odat.cu ea, se fncheie st irul dd execufe. La linia 5 se pomest ial de execuie, prin creaea une instane a clase Thread avind ca paramettu Runnable chiar clasa noastr, Rezltatal aga de program este Java.lang.Exception at TestRunnable.run(TestRunnable. java:9) at java. lang. Thread. run (Thread. java: 484) coea ce dovedeste cf metoda run () a clasei Test Runnable a fost apelatt dde metoda rua () aclasci Thread. Programa din Listing 8.2 reprezinttvarianta Runnable a programlai din Listing 8.1, Remarcajidferenjele minime inte cole doua variant. La linia 1, casa SimpleRunnable declar ca implementeazAinterfaja Runnable ‘poi, Ia linia 30 fru de executie se ereeaz& trnsmind a instana a clasci SimpleRunnable consinictonli casei Thread. In rest, cele dou pro- srame sunt ientice 8.3 Accesul concurent la resurse Un program care ruleazi pe un singur fir de execusie poate fi privit ca unicd entitate care se mige& prin spajiul problemei ficand un singur lucra la 22 Listing 8.2: Exempla simplu de fire de execujie ereate prin implementarea in- terfefei Runnable public class SimpieRunsable Implements Runnable a >> private int countDown = 5 {private statle Int theeedCount = 0: > private int threadNumber : 5 public SimpleRunnable() of + threadNumber = 44 theeadCount + ss System-ourprintin(*Creez firul ne. * + threadNumber ) nd 5 public vod run() SS white cerwe) "ot © System.out. peintin(*Fir ar. * + threadNumber + *(° + e countDown +*)"): 'Hf(-countDowa == 0) So sd . 4 an public static void main(String (1 ares) of h for(int i= 0; i < 3; 148) > =" new Thread ( new SimpleRunnable () ). start () 4) hs System.out. printin(*Firele de executie av fost poraite."): 23 tun moment dat. Deoarece existi doar o singuri entitate nu este necesar si ne punem problema daci doua entitiji ar putea accesa aceeasi resursii in acelasi timp, cum ar fi de exemplu situajia a doua persoane care igi parcheazi masina {n acelasi loc simultan, sau care incearca si jas in acelasi timp pe usa, sau chiar si vorbeascd in acelasi timp, {in cazul mai multor fre de executie, nu mai avem o singur& entitate gi exist itatea ca dour sau mai mule fire de executie 84 incerce si utilizeze acelagi timp. Nu intotdeauna accesarea unei resurse simultan este © problems, dar sunt situsii in care aceste coleziuni trebuie prevenite (de exemplu, dous fire de execufie care acceseaza simultan acelagi cont in banc’, imprimanta etc.) [Exemplul simplu de mai jos pune in eviden{a problemele care pot si apari {ntr-un program multithreaded (care ruleaz’i pe mai multe fire de executie): sau care dorese si tipireasca la acecas + public = Counter } private int count = 0 //counter incrementar de increment () {publics int increment () st tant aux = count: Clasa de mai sus este extrem de simpli, avind un singur atribut si 0 guri metoda. Aga cum fi sugereaza si numele, clasa Counter este utilizata entra a numéra diverse Iucruri, cum ar fi numarul de apasiri ale unui bu- ton, sau numarul de accesiti al unei pagini web. Esenja clasei este metoda increment () care inerementeaza gi returnea7 valoarea curenti a counter- ului. Desi clasa Counter pare complet inofensiva, ea consituie © potential’ sarsi de comportament imprevizibil int-un mediu multithreaded, ‘Si consideriia en exempla un programa Java care contin dou fire de exe- cutie, amindous find pe cae si execute urmitoare lini de cod Int count = counter. inerement 5 Programatoru nu poate nici si controleze gi nic si prezici ordinea in care cele doua fire de execujie vor fi executate. Sistemul de operare (sau masina virtual Java) define controll complet asupeaplanficiri frelor de execute in consccina, no exists nici o certitudine in privinga cara fir de executie se va execu, sau cat timp va fexecutat un anumit fr de executie. Orice fir de execuje poste fintrenipt printvo schimbare de context n orice moment. Mai mult, dou fire de execuse pot rua simultan pe dou’ procesoare separate ale unei masini mukiprocsor. 224 1.3. ACCESUL CONCURENT LA RESURSE ‘abela 8.1 descrc o posbi secvensi de execusie a celor dou fre de ex- couse, In acest scenaru, primal fr de execufe este lsat si rleze pnd cind fncheieapellcatre metoda increment () apo, cel de-aldoilea fr face ace- lagi cra, No este nimicsurprnzitoria acest scenari, Primul fir va incrementa valoarescontoruhi I 1 iar al doilea ova incrementala 2 ‘Tabela 8.1: Counter Scenariul 1 Firde exeanjie? Fir de exeaijio? count [ane count = counterinerement) = Tntaux = count 710 = countes = return aux 710 = = ‘Count = counterinerement = aux = eount = counter 72 = return aux 777 ‘Tabela 8.2 descrie 0 secventi de executie oarecum diferiti. In aceast si jie, primul fir de executie este intrerupt de schimbare de context chiar in timpul executiei metodei increment (), Primul freste astfel suspendat tem- porar si se permite execufia celui de-al doilea, A doilea fir executa apelul eitre metoda increment (), mirind valoarea contorului la | si returndnd valoarea 0. Cand priml fir igi va relua execu problema devine deja evidenta. Valoarea ‘contorului este erescuti la 2, dar valoarea retumaté este tot O! ‘Tabela 8.2: Counter Scenariul 2 Firde exccujio? Firde execufie? ‘count [aux Gount = counterinerementO = 0] int aux = count 710 = 0 [0 = ‘count= counterincrement |_O | — = faux = count 0 0 | 0 = ‘eounte IL To = eturn aux 1 oo county = 2 [0 Fetum aux 10 = zo Examingind scenariul din Tabela 8.2, veji observa o secvengA interesanta de 25 £83, ACCESUL CONCURENT LA RESURSE cexecutie a operajilor. La intrarea in metoda increment (), valoarea atribu- tului count (0) este stocata in variabila local aux. Primul fir este apoi sus- pendat pentru 0 perioad&, timp in care se executi celAlalt fir (este important Sh observim ci valoarea lui count se modifica in aceasta perionda), Cind primul fir igi reia execufia, el inerementeaza corect valoarea Iui count si re- ‘urneaza valoarea din aux. Problema este ci valoarea din aux nu mai este corecti, deoarece valoarea celilat fi. Pentru a ne convinge de faptal c& scenariul din Tabela 8.2 este intr-adevar posibil, am extins clasa Counter prezentati anterior, adaugindu- i clasa interioara (vezi paragraful 5.7, pagina 145) Counter Test (Listing, 8,3) derivati din Thread. Metoda run () aclasei Counter Test (linille 34- 42) apeleaza intr-un ciclu infinit metoda increment () a clasei Counter, Variabilele check? si check? declari gi inifializeazi cate un obiect de tip CounterTest care ruleazi pe un fir de executie separat (firul de execuie este ponit chiar in constructorul clasei Counter Test care apeleazi metoda start () in linia 30), Listing 8.3: Clasi Java care evidenjiaza problemele care pot apiea la partajarea resurselor cpublle class Counter tt private int count = 0; //counter incrementat de Increment () Vinitializeaza ti porneste primal thread de verificare private CounterTest check! = new CounterTest () + ‘ Hinitializeaza si porneste al doilea thread de verificare + private CounterTest check? = new CounterTest () + public int increment () mi UC count t= eux+t) wt 5 System. out. printin("Oops! Ceva au ein regula... "+ 5 this.count 4" "4 aux) 5 pod wo a fee hn ¥ Clasa care evidentiaza problemele de sincronizare 3 cate metodai increment 3 publle class CounterTest extends Thread = ) | fue Construieste si porneste firul de execute. +/ 1.3. ACCESUL CONCURENT LA RESURSE public CounterTest() i this.startO ny fee Apeleaza metoda Increment () imtr-un elelu Infinit. as bs publle yold. run) » % System. out. printin ("Firul * + this. getNameQ) + 5 “a porait") : m fora) » * increment () « ) ey public static void main( String (] args ) “f Mereaza 0 instanta a clasei Counter new Counter () “1 Jn mod aparent paradoxal, dupa seevenja de instruciuni Ia linia 13 se verfic& daca valoarea variabilei count este diferita de aux+1 ie¢ count != aust) Acest test ar fi complet inutil intr-un program care ruleaza pe un singur firde ‘execufie, dar nu si in eazul nostru, La rularea programului Counter . java, acesta va afiga (valorile afigate difera, desigur, de la 0 execufie la alta) Firul Thread-0 a pornit Firul Thread-1 a pornit Oops! Ceva nu e in regula... Thread-1 18777999 18247501 Oops! Ceva nu e in regula... Thread-1 55129926 54599470 Oops! Ceva nue in regula... Thread-0 81760783 281229276 Oops! Ceva nue in regula... Thread-0 104069819 103556887 Oops! Ceva nu e in regula... Thread-o 118311248 27 117779680 Oops! Ceva nu e in regula 278475302 ‘Thread-1 279005154 Din cele afigate reese ct test de Ia linia 13 na este deloe inutil, Se poate intémpla ca unul dine fircle de execute ale clasei Counter Test (st zicem check!) sf fie fntreruptimediat dupa ce a fost atrbuita valoarea lui count variable aux, darinainte ca metoda si apuce si rturneze valoaea in aux (ca in scenariul din Tabela 8.2, In aceasta state, celalat fir de execute al clase Counter Test, check2, va continua. inerementezevaloarealui count de bi aumienedeterminat de of, dupl care control va fi din nou prebat de fral de executieintrerupt, check. Acesta va avea noua valoare ahi count, eae a fost inte timp inerementata dar vecheavaloare lui atx, care (ind varab local) a fost salvatipestivinaint de schimbarca de context, de aici rezultind inconsistena somnalti de tstl din linia 13. Desig, sansele ca primul fir de execuje si fie inrerupt chiar up ce a fost incrementat count. sunt foarte mci, dovadi g fatal ci aceastssitaie a apirut dupa peste 18 milioane de apeliri ale metodei Sncrement (). Tous, gnsele exists, si neluarea lr in considera poate avea consecinje grave asuprafuncjoniri unui program. Problema pusi in evident de seenariul din Tabela 8.2 poarti mumele de inconsistent a concurenté (engl. race condition) rezultatul unui program de~ pinde de ordineain car sau exccutat fice de execuie pe procesor. In general ht este deloc indicat si se permit incosistene a concuren in ezulatele unui program. Noi nu putem sti niciodatsin ce moment un fi de execufie este ex- cata sau fntreopt. Inchipuiji-vl i suntei ajezat la © masé eu o Tingurd in mind gata-gata si gust dintro salatk de fructe delicioasi car se afin faa dhumneavoastrs. Vi indreptag plini de sperani ingura etre salata de Fact si, chiar in momentlin cae i atingfi alata, aceasta dispare irk urm (deoarece fia! vostru de execu a fost suspendat, tne timp, alt fir de executie a fu- rat mancarea). Mergand cu analogia mai departe, damneavoastr nu vey imp si reacfionai ta dspargafafurei (fiecare fir de execufie ae iluzia ch execut Singur si continau pe proceso) si vei tnfigelingora in masi, provocind asfel {ndoirea ei (adeseori, folosirca simultan a unei resurse conduce la coruperea “i, Exist situ care nu are imponangi dack o resus este accesati in ace- lagi imp de mai malt fire de execuje (mancarea este pe o alt farfurie). To- tusi, pent ca programele mulihreaded (rom. cu mai multe fire de execuie) "Desi mu am preczat car acest ers, variable locule sunt distncte penta fear ir de exe- ‘ule in pane Tou atsbtceelsclor sunt parte deere toute firele de execu are ular tan moment dt 228 s fancjioneze, trebuie si existe un mec: cesului la o resursi de etre mai multe thread-uri, méicar in timpul perioadelor critice. S& ne imaginam ce s-ar fi imtamplat dac& metoda increment () ar fi fost utilizatl pentru a actualiza contul in banc al unei persoane in loc si srementeze pe count. Pentns 0 bane’, corectitudinea conturilor este de im- Portangi maxima. Daca o bancd face erori de calcul sau raporteazA informati orecte, cu siguranga nu isi va inefinta clien tice programe multithreaded, chiar si cele scrise in Java, pot suferi de in- consistengi la concurengi. Din fericire, Java ne pune la dispozijie un mecanism simplu pentru a controla concurenja: monitoarele. 8.3.1. Sincronizare Exist multe lueriri de programare gi sisteme de operare care se ocupit de problema programirii concurente. Concurenja a fost un subiect foarte cercetat {in ulimii ani, Au fost propuse si implementate mai multe mecanisme de control al concurenjei, printre care © sectiunile ertice; © semafoare; © mutexuris «# blocarea de inregistrr in baze de date; © monitoare, Limbajul Java implementeszo variant a monitoarelor (engl. monitors) penis controlul concurenjei. Conceptul de monitor a fost introdus de C.A.R. Hoare (acelagi Hoare care a propus gi algoritmul de partfonare de la Quicksort) in anul 1974 intro Iucrare publicatd in Communications of the ACM. Hoare de- serie in aceastéIucrare un obiect special, denumit monitor, care este utilizat pentru a furniza excluderea reciproct pentru un grup de proceduri ("excludere reciproca” este un mod elegant de a spune “Un singur fr de execufe fa un mo- ‘ment dat’). in modelul propus de Hoare, lecare grup de proceduri care necesitt excludere reciproci este pus sub controlul unui monitor. in timpul execute ‘monitorul permite si se execute doar o singur procedur flats sub controlul Jui fa un moment dat, Dac un at fir de execufie incearct s8 apeleze 0 pro- ceduri conrolats de monitor ael fir este suspendat pin fn momentul fn care fiat curent apelul 29 £83, ACCESUL CONCURENT LA RESURSE Monitoarele din Java implementeaz4 indeaproape conceptele iniiale ale Iui Hoare, aducind doar efteva modifiiri minore (pe care nu le vom prezenta in aceasti carte). Monitoarele din Java impun excluderea reciproc la accesarea de metode, sau, mai exact, excluderea reiproci I accesarea de metode sin- ‘ronizate (vom vedea imediat un exemplu coneret de metod sincronizat). {In momentul in care se apeleaz8 o metods Java sincronizath se declangea un proces deosebit de lborios. In primal rnd, magina viralA Java va localiza ‘monitorul asociat cu obiectal a cérui metodi este apelata (de exemply, dack se apeleazi counter . increment (),masina virtual va localiza monitoru! Jui countez). Orice obicet Java poste si aiba un monitor asociat, desi, din totive de eficienji, magina viruald creazi monitoarele doar atuncicind este nevoie de cle, Odatce monitor este gist, magina virtual incearcd si atrbuie ‘monitorulfiruui de execuffe care a apelat metoda sincronizatl, Daci monitorul fi este atribuitaltui fir de execufie, se va atribuifirului curent, cdrua fi este poi permis sicontinue cu apelul metodei, fn situsfia in care monitoruleste deja definut de cite un alt fir de execufe, el nu va putea fi atribuit firuui curent, care va fi pus in asteptare pnd cdnd monitorul va fi eliberat, in momentul in care ‘monitorul va devenidisponibil, aceasta va fi atibuitfirului de execufie curent, ‘are va putea continua eu apelul metode Metaforie vorbind, un monitor afioneazS ca un fel de seeretar alata in- trarea in brou aunei persoane foarte solicitae. in momentul in are se apeleazt © metods sineronizatt,secretara permite firului apelants& teaet, dupa care {nchide usa de la birou, Atta timp cat fl este tn cadrul metode sineronizate, apelurile ete alte metode sincronizate ale obiectului sunt blocate. Aceste fie se aseazi la coadi in faa usi de la birou, ateptind ou ribdare ca primal fir plece. in momentu in care primul fir piriseste metoda sincroniza,secretara ‘Toji modificatoriiclasei Account sunt declarajica find synchronized. Aparent, aceasti clas nu ar trebui si aibii nici un fel de probleme legate de inconsistenga la concureng’. $i tous, ea are! Pentru a inelege inconsistenta la concurengi de care suferi casa Account, sii vedem cum lucreaziio bane cu conturile, Pentru o bane este de o impor- ‘angi major si mengins corectitudinea datelor din conturi, Pentru a evita ra portarea de informa inconsistente, bincile preferi ca, in timp ce se realizeaz’ © tranzactie, si dezactiveze cererile privitoare la soldul dintr-un cont. Astfel, cliengii bancii nu pot si primeasci informasiipreluate in timpul unei tranzacyii parfial incheiate. Metoda get Balance () din clasa Account mu este sin- ‘ronizati, iar acest fapt poate conduce la anumite probleme, ‘S& presupunem ci un fir de executie apeleaz metoda sincronizati trans- fer (), pentra a trece suma de 10 milioane de lei din contul curent in alt cont Mai mult, fil nostru de executie este intrerupt de o schimbare de context ime- iat dupa ce a executat linia 16: tts withdraw (amount): {in acest moment, suma de 10 milioane fost extras din primut cont, dar {ned na fost depozitatt tn celilalt cont, Daci un alt ir de executie va apela metoda (nesincronizati!) get Balance () pentra cele doud contri implicate {in transfer, aceasta va putea accesa nestingherit&informatia din cele doua con- tori Astfel, etBalance () va raporta ca suma de 10 milioane de lei a fost 234 1.3. ACCESUL CONCURENT LA RESURSE cextrast din primul cont, dar aceasti sum’ nu se va regisi in contul destinatie, deoarece metoda transfer () mu a apucat si actualizeze acest cont inainte de afi inteerupta! Astfal, client s-ar putea introba unde a disparut suma respec- tiv’, Dacd getBalance () ar fi fost sincronizata, acest scenariu nu ar fi fost posibil, dcoarece apelul ei ar fi fost blocat pana la incheierea tranzact 83.3 Instruetiunea synchronized ‘Metodele sincronizate nu pot fi folosite tn orice situajie. De exemplu, grurile Java nu dispun de metode, cu att mai pujin de metode sincronizate. Exist totusi multe cazuri in care dorim ca accesul la elementele unui sir si fie sin- Pentru a rezolva aceasta situatie,limbajul Java ofera sioalt& convengie sintacticd prin care putem interactiona cu monitorul unui obiect: instrucjiunea synchronized, cu urmitoarea sintaxd: synchronized ( expresic ) Exccutia une instrutiuni synchronized are accasiefet ca si apelarea vei metode sineronizate: irl de execuje va tebui si dejindun monitorinainte dea exceuta inateuct iune (care poate f simp sau compu). In eszal insirueianii synchronized se va utiliza monitonl obieetulatobfinut prin cvaluarea hii expres (al cei rezultat nu tebuie si fe un ip primi). Insriionea synchronized este cel mai adesea folosita pens a seria- liza acces a obiecte de tip array. Secventa de cod de mai jos este un exempht de cum se poate sriliza acceso concurenfal Ia elementele unt lan Incrementeaza elemental de pe poritia poz. +/ svold increment(byte[] sir, Int poz) synchronized ( sie) ¢ 6 siel por J+e {in exemplul anterior, masina virtual Java va atribui monitorul Iui six firului de executie curent, inainte de a incerca sa incrementeze elementul de pe Pozitia poz. Alte fire de executie care ar incerca si objin’i monitonul acest gir "Acestevempla nu este concladent petra multe inci din Romania, cre au neve de un iter sal de 2 ze pent ca sma transfert dinteun ont par in cla cont “Dei nu sunt obit in adeviratl sens al covénu, srl din Java au anumite ropiet speciticecbiectelor, pine care monitor. 235 £83, ACCESUL CONCURENT LA RESURSE vor fi forjate st astepte paind cand se incheie operafia de incrementare. Trebui {nsd si avem in vedere faptul ci accesul Ia elementele sirului va fi totusi permi {in cadrul altor instrucfiuni care nu sunt sineronizate pe monitorul siruli Instrucjiunea synchronized este utili i atunci cind dorim si modificim un obiect fart a folosi metode sincronizate. Aceasta situajie poate si pari atunci cind se modifica atributele publice ale unui obiect (deyi am aritat deja ct utilizarea de atribute publice nu este de dorit) sau se apeleazii o metodi care nu este sincronizaté (dar ar trebui si fie) si noi nu o putem modifica (de exemplu, pentru cd este mogteniti de la un alt object) lati un exemplu: tyold metoda( Oct obicet ) >> synchronized ( obiect ) ot + | object. metoda_care_ar_teebui_ss_fie_sineronizata_dar_nu_e () + ) ) (© metoda sincronizati este echivalenti cu metodi nesineronizati ale clrei instructiuni sunt cuprinse intr-un bloc synchronized pe monitorul obiectu- Jui (this). Astfel, metoda ‘synchronized vod 0) M a : este echivalenti cu metoda sveld £0 Ht Observatie: Instrucjiunea synchronized ne ofers posibilitatea de a utiliza monitoarele oricirui obiect Java. Totusi, folosirea instrucjiunii synchzonized {in situajii fn care ar fi fost suficient& declararea unei metode sincronizate duce ‘uneorila un cod greoi si dificil de depanat. A@ugarea modificatorului syachzo- nized la antetul unei metode defineste foarte clar ce se petrece atunci cind metoda este apelati 236 8.3.4 Competitie asupra monitoarelor Se poate intémpla ca doua sau mai multe fire de execute si fie blocate in asteptarea objineri aceluiagi monitor. Aceastsituafe apare atunci ind un fir de execuje dejine monitorul unui anumit obiect. Dac un alt fr de execufie arcs execute una din metodele sineronizate ale aceluiagiobiect, fil va fi suspendat, in agteptareaeliberrii monitorului. Dac un al treilea fir de execufie arc gel sh apeleze o metodi sincronizat a obiectuu, va fi gi el suspendat in momentul in care monitorul va deveni disponibil vor i dous fire de execufie care agleapt s 1 obyind fn situaia tn care dou sau mai multe fire de execuje asteaptt objinerea aceluiai monitor, magna viruald Java va trebui si aleagi doar un singur first Si atibuie acesuia monitorul, Nu existé nici o garanjie in privinga regulit dup care masina virwali va decide care fr va ales. Specificaialimbajulut Java prevede ca doar un singur fir de execujes& objind monitor, fra preciza un algoritm dupa care masina viral si aleagfiu! de execufie. De exemplo, masina viwali Java care ruleaz§ pe Solaris, lege firul de execuje fn funcyie de pririate eu primul venit-primul servit in cazal in care prioitiile sunt egale Totugi, magina virtual Java de pe Win32 foloseste algoritmii de planificare specitiei Win32, Astfel, nu este posibil si prevedem ordinea in care fiele de executie vor objine un monitor in eazul in care mai mule fie de exccuje sunt in asteptarea hui, si de accea trbuie si evita serierea de cod eare ar depinde de accasti ondine 8.3.5. Sincronizarea metodelor statice ‘Am viizut deja c¥, pentru a putes fi executate, metodele care sunt declarate ‘fi sincronizate, sunt obligate si dejind monitoral obiectului pentru care au fost apelate. Ce putem insi spune atunci despre metodele statice, care, dup’ cum stim, nu trebuie neapirat apelate in conjunetie cu un obiect (metodele statice sunt specific claselor, imu obiectelor)? Solujia oferiti de Java este simpli: in momentul in care se apeleazsi o ‘metodi staticX sincronizati, aceasta va trebui si obfind un monitor special, care este asociat flected clase n parte. Cu alte cuvinte,fiecare clas Java are asociat tun monitor care controleaza aceesul la metodele statice sineronizate ale clase Rezulti de aici ci doar o singur’ metodi static’ sincronizati se poate executa la un moment dat in cadrul unei clase Un fapt care merit remarcat este c&, in implementarea actual’, magina vit= ‘walt Java foloseste pentru sincronizarea metodelor statice monitorul instanjei 237 £83, ACCESUL CONCURENT LA RESURSE de tip java. 1ang.Class asociat clasei respective. Aga cum am vazut si {in paragraful 5.8.2, pagina 165, instangele clasei java. Lang. Class deseriu, toate clasele si interfejele existente in cadrul unei pics ccujie. Fiecare clasi sau interfaya Java (chiar si tipurile primi © instanja de tip java. 1ang.Class. Obiectele de tip Class sunt constru- ite automat de citre masina virwali Java pe masuri ce clasele sunt inedrcate {in memoric. Prin intermediul unei instanfe java. Lang. Class asociata unei clase se pot objine informatii despre clasa respectiva, cum ar fi numanul de atribute gi tipul lor, metodele clasei, pachetul din care clasa face parte etc Instanja java. lang.Class asociati unei clase poate fi obyinuti folosind metoda getClass () definiti chiar in clasa Object. Ajungi in acest punct, Vi intrebayi, probabil, la ce ne foloseste si avem o clas care si descrie con- Jinutul fiecirei clase? Rispunsul este ci aceastl clasi este piatra de temelie a ‘aga-numitului Reflection API (vezi capitolul 5.8.2), care este folosit in debug- -ger-e5, serializare gi deserializare de obiecte ete Pentru a ne convinge de faptul ¢& metodele statice folosese monitorul aso- iat instanjei java. 1ang..Class, si studiem clasa StaticHonitorzest, de mai jos: public class StaticMonitorTest extends Thread i publle vold cum) i 5 synchronized ( getClass () ) sot > System, out. printin ("Se exeeuta run Q")s try [Sleep (5000); } eateh (TnterruptedException _) ( } ‘0 oan {public static synchronized void staticP Q) of Se System. out. printin ("Se exeeuta statier ()"): Stay (sleep (5000); } eateh (InterruptedException _) ( | “4 % public static vold main(String [] args) t forest Q. start Os new StatieMo » statleF O: La rularea acest clase pe Linux sau in32, se afigeazi mesajul “Se ex- *aplicaifolosite in depanara programelor 238 ecuta static ()”, dup’ care urmeazi o pauzi de 5 secunde, se afigeazi “Se executa run)” si programul se incheie dupa o pauzii de ined 5 se~ cunde. Rezulta clar de aici ci monitorul folosit pentru metoda staticd este ace- Iasi cu monitorul obiectului de tip Class asociat. Nu se stie daci ne putem baza pe acest comportament si in versiunile viitoare de Java. Un Iucru este to- tugi cert: doua metode static definite in cadrul aceleiasi clase vor utiliza acelasi 83.6 Monitoare si atribute publice Am aritat deja cl declararea de atribute publice nu este de dorit, Acestlucru System-out-printin (am iatrat in metoda rua”): h otherThread ssyneMethod (): sd 5 public synchronized void syneMethod () a 2% try ( Thread. steep (2000): } eateh(IaterruptedException e) ( } % System-out-printin(*Am intrat in metoda sincronizata”): ny fnacestexemplu, metoda man ()lanseazi nile 15-16 dou fre de exe- cutie, fecare dintreeleapelind metoda sincronizata run () aclasei Deadlock. ‘Cand primul fir se tezeste (@upA ce a dormit 2 secunde) Ia linia 23 afigeaza mesajul de intrare in metoda run (), dupa care incearca si apeleze metoda syncHethod () a ccluilalt fir de executie Ia linia 24. Evident, monitor chill object este defint de al doilea fr de executie, aga ct priml fir st si asteaptd uli. In momentl in care se tezestc, al doiles firinccarcé si apeleze syncMethod () a primului fi: Cum monitor primu- lui fir este deja deyinat de metoda run () aacestia ial doilea fir va intra in asteptare. Cele doud fie de execufie vor agtepiaunul dupa all si nu igi vor continua nciodathexceuja. Aces fapt este demonstrat gi de messjeleafigate la execafiaprogramulu am intrat in metoda run am intrat in metoda run H anunta firul consumator co befferst au mai e gol = notity Os “ fee Extrage primul caracter din Buffer. Daca bufferut tus este gol, se asteapia pana cand se obtine 0 notificare S tde le metode gett). + & public synchronized char get) mii fh while (isEmpty 0) » ” ( a wait: eB ’ % cateh(InterruptedException e) { sy char © =buf{0l; 5 Wdeplaseaze clementele din buffer la stanga System. arrayeopy (but, 1, buf, 0, —— last): % — Hanunia Jira producator ca’ bufferul me male plin S notity Os ay a Observatie: Cititori atengi, allay la prima confruntare cu metodele wait () si notify () ar putea observa 0 contradictie. S-a mengionat deja faptul ci pentru a putea apela metodele wait () $i not ify (). ful de executie trebuie si defini monitorul obiectului. Astfel, dact un fi de executie objine monitorul ‘unui obiect gi intes apoi in asteptare printe-un apel al metodei wait (), cum va putea alt fir de executie si obsind monitorul obiectului pentru a putea no- tifica primul fir? Oare monitorul nu este inc’ in posesia firului care asteapts, {mpiedicand astfel al doilea fir n a-l objine? Rspunsul la acest aparent para- dox este dat de modul in care este implementati in Java metoda wait (): aceasta elibereazi temporar monitorul dup’ ce a fost apelat, si objine din now monitorul inainte de a se incheia. Astfel, metoda wait () permite si altor fire de executie si objind monitorul obiectutui si (eventual) si apeleze metoda notify() Clasa BufZex este doar o simpli zond tampon de memorie $i nimie mai mult, Se pot adauga elemente in buffer, folosind metoda put () si se pot ex- ‘rage elemente din buffer folosind metoda get (). 248 {4 COORDONAREA FIRELOR DE EXECUTIE Observati modolin care s-au utilizat wait () si motAY ()tnaceste metode. in cadrul metodei put () atta timp et bfteru este plin, se intr i asteptre Astfel, nu se vor mai putea aduga noi elemente in buffer pina in momenta {in care firal producitor nu este noiieat (Ia linia 60) de catre consimator au fost extrse clemente din buffer. Apelul metodei notify () din fnalal metodei get () are roll de a activa fial de execuie care ateapt in cade metodei pt () la linia 34 (dack acest exist), permitindsiastfel st adaage un nou caractern But fer. Un rajionament absolut similar este valbil i pen- tru metoda get (). in care se asteapa ct timp buffer este gol, dup care se exirage un caracter ise notified noua stare a bufferuh Clasa Buffer Test de mai jos, construieste un Buf fer, dupaicare porneste pe fire de execujie separate producatorul si consumatorul: public class TesiButfer ( ) public static void main(String args(1) ae 5° Buffer b = new Buffer( 50): {mew Thread (new Producee( 6) ). start () + new Thread (new Consumer( 6) ). start () i no 1 Rezultatulafisat la consol (in cadnul clasei Consumer) confirma faptul ek firele de execusie au fost corect coordonate: ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZA BCDEFGHIJKLMNOPQRSTUVWXYZAB CDEFGHIJKLMNOPQRSTUVWXYZABC DEFGHIJKLMNOPQRSTUVWXYZABCD EFGHIJKLMNOPQRSTUVWXYZABCDE FGHIJKLMNOPQRSTUVWXYZABCDEF GHIJKLMNOPQRSTUVWXYZABCDEFG HITKLMNOPQRSTUVWXYZABCDEF Implementarea metodei get () din clasa Buffer nu este foarte eficient’, La fiecare apel al acestei metode, toate celelaltecaractere din buffer trebuie de~ plasate cde stinga, © problemi de Ia finalul acestui capitol propune o imple- ‘mentate mai eficienti a clasei Buf fer folosind o coada alocati static (detalii despre cozi in cel de-al doilea volum, dedicat structurilor de date si algorit- milor). 49, {84 COORDONAREA FIRELOR DE EXECUTIE 8.4.4 Detinerea monitoarelor Exist o restricyie important in folosirea metodelor wait () gi notify () aceste metode pot fi apelate doar daci firul de execusie curent dejine monitorul obiectului. in multe situafii, metodele wait () si notify () sunt apelate in ‘cadrul unor metode sineronizate (dejinerea monitorului fiind astfel asigurats), ‘cain exemplul de mai jos: bite synchronized void method() white (1 condition) i © wait 0: in situajia de mai sus, modificatorul synchronized ne asigura de faptul i firul de execusie care apeleaza wait () define deja monitorul in momentul apelulu, Ce se intdmpld inst dact se incearcd apelul wait () sau notify () fri ‘define monitorul obiectului (de exemplu, in cadrul unei metode nesineroniza- te)? Compilatorul nu poate si igi dea seama daci existi un apelilegal (Fir a ‘define monitorul) al acestor metode (de exemplu se poate ca o metodi nesin- ‘cronizati si apeleze wait (), dar aceasti metoda si fie apelatt de 0 metod’t sincronizati). Asadar, singura posibilitate este ca, in timpul execufiei, dact se ‘mtdlneste un apel al metodelor wait () sau not ify () flirt adefine monitorul obiectului si se genereze o exceptie, Aceasti exceptie se numeste I1legal- MonitorStatezucept ion gi este aruncati de masina virtual Java ori de cite oi intélneste un apelilegal al metodelor wait () sau notify (). Clasa MonitorTest de mai jos evidenjiaza ce se petrece in momentul in care se apeleaz metoda wait () fra afi definut in prealabil monitoral clasei public ¢ MonitorTest 1} public static void main(String [] ares) ot + | MonitorTest mt = new MonitorTest (): © mt.method (): ) public void method() of Say aot ® wait 0: {4 COORDONAREA FIRELOR DE EXECUTIE wy %S cateh(InterruptedException e) aan ed a ” acd vejiincerca sh executayi aceasta clas, veti primi urmatorul mesaj Exception in thread "main" java.lang.11legalMonitorStateException at java.lang.Object -wait (Native Method) at java.lang.Object .wait (Object. java: 420) at Monitor Test .method (MonitorTest. java:13) at MonitorTest.main(MonitorTest. java:6) Pentru a evita o astfel de excepie, este necesar ca de fiecare dati cind apelayi metoda wait () pe un obiect si Vi asigurafi cd firul de execute define moni- torul acelui obiect 8.4.5 Utilizarea instructiunii synchronized Instncjiunea synchronized poate fi sien flosith pent a realiza co- ondonarea frelor de execufe. In cele mai multe cazur uilizarea metodetor sincronizat este suficient, si datortsfaprtuic& sintaxa lor este mai simpli cle sunt de prefertinsiucfiunii synchronized, Exist totus doud situa {in care utilzarea metodelorsineronzate neste de dori, sau no poate rezolva problem, Daci metoda care confine un wait () sau notify () este foarte longi (si nocestéun timp de execuie semnifcaiv) este preferabil s se sineronizeze doar secventa de cod care este strict necesaré pent a menfine consistent In concent ‘Adessor este neces si coordonien metode obiecte diferite. in aceasti situafie, utilizarea de metode sineronizate nu are nici un sens, deoarece apelul Iuj not fy () din cadrul unei metode sincronizate a unui obiect nu are nici un cefect asupra firului de execufie aflat in asteptare fn cadrul unui wait () pe un alt obiect (metodele objin monitoare distincte)! ‘S& presupunem de exemplu c& avem la dispozife o clast simpli Buf Sex ‘denticd din punct de vedere al interfejei cu clasa Buf fer din paragraful 8.4.3, dar care a fost conceputi si scris& pentru a funcjiona corect pe un singur fir de execute 251 {84 COORDONAREA FIRELOR DE EXECUTIE public Ht © Buftert private char{] buf; //retine elementele din buffer Private Int last; //ultima pocitic ecupata {fae Construteste un buffer cu size elemente */ + public Buffer! (Int size) = new char [size 1: 8 fee Intoarce true daca bufferul ¢ plin.+/ us public boolean. isFull() sf return (last ed bur. length): fee Intoarce true daca bufferul ¢ gol. +/ 5 public. boolean” isEmpty () cil : | return (last ad B fee Adauga caracterul ¢ la buffer. */ % public synchronized void put(char c) > » bufllast ++] a Bi fen Extrage primul caracter din Buffer. +/ public synchronized char zet() rt M0 char c= burtol: % Udeplascare lementete din buffer le stanza System. arraycopy (but, 1, buf, 0, ~~ last): mo : » Observati cd, spre deosebire de clasa Buf Ee din paragraful 8.4.3, aceasti buffer. wait () 5 2 eateh ( InterruptedBxception © ) put((ehar CAT + (%26))) » buffer notify () : * Diferenja fade clasa Produces apare Ia metoda run (), care confine «od suplimentar pentru realiza sincronizarea cu consumatorl fn primol rind, Jainia 14 se solicit monitoalbaffealu,flosind insrutiunea synchronized (buffer) ‘ 1 Instucjiunea synchronized este ullizata in acest caz din dou motive in primul rind, rebuie asiguratt consistena la concuren( prin evitareasituaiet dea se serie gi citi buffer in acelagi timp. fn al doilea rind, instrucyiunea synchronized garanteazi obfinerea monitorului obiectului buffer, pe care se va putea apoi apela wait () fn cazul fn care bufferul este plin (linia 20), respectiv not ify () dupitce s-aeitit din buffer (linia 26). Remarcaffaptal wait () sinotify () au fost apelate in conjuncjie eu obiectl bus fer: 253 {84 COORDONAREA FIRELOR DE EXECUTIE butter. wait) buffer notify 0 deoarece coordonarea se face utilizind monitorul bufferuli Implementarea consumatorului este similara cu cea a producdtorului i este realizaté de clasa Consumer de mai jos: public class Consumerl implements Runnable t } private Buffer! buffer 5 publte Consumer! (Buffer! buffer) ot > this. buffer = buffer no % publle vold run) af th for (int 120; 1<250; 144) oot te aynehronized ( buffer ) * c . while ( bufter.isEmpty () ) f tC " wy * i » buffer. wait () 5 a , - eateh ( InterruptedE xception © ) 2 a " ) : System. out. print (buffer. get() + "")s » buffer notity Qs p ’ aa) > ” Pentru a testa noua rezolvare a problemei bufferului, am creat clasa Test- Buffer, absolut similara clasei Test Buf fer: spublic class TesiButferl public static vold main(String args 1) + Buffer! b= new Buffer! (2) + new Thread ( new Producert( b )). start () : + mew Thread ( new Consumer! ( b ) ).start() ) ) 254 {4 COORDONAREA FIRELOR DE EXECUTIE La executia acestei rezolvarea precedenti, ceea ce dovedeste c& $i aceasti abordare este vi ase, se va afiga acecasi secventii de caractere ca si la 5, 8.4.6 Un alt exemplu: consumatori si producditori multi Este posibil ca mai multe fie de executie si fie in asteptare (wait ()) pe acelagi object. Aceasti situajie poate si apari dacti mai multe fire de execujie asteaptit aparitia aceluiasi eveniment, sau daci exist mai multe fire de exe- ‘cujie care partajeazi o resursi unici, Si luiim din nou exemplul clasei Buf Ee prezentati in secjiunea 8.4.3. Bufferul era utilizat de cdtre un singur producitor sin singur consumator, Ce s-ar petrece inst, dac& ar exista mai multi pro- return (last ad 0: fe Adauga caracterul ¢ la buffer. Dace bufferul este plin Dt atunel se incrementeaza writersWalting 4 tsi ge asteapta pana cond se. obtine {4 COORDONAREA FIRELOR DE EXECUTIE % 20 motificare de ta metoda geri). of % public synchronized vold put(char c) ( 0 while( isFUllO)) » Muy ™ fl » writersWaiting 44; ” wait: sy hs cateh( InterruptedException ©) . O “ writersWaiting yo > bufllast ee) =e: i If (readersWaiting > 0) oot S| notityA(: ae “ > fee Bstrage primal caracter din Buffer. Daca bufferat nb este gol, se incrementeaza readersWaiting si re St asteapra pana cand se obline 0 motificare bp tde la metoda get(). + public synchronized char get() sf while isEmpty Q) > ot a ty of « readersWalting ++ « wait: 5 ) eateh(IntercuptedBxception e) * } « sadersWaiting——: an) © char ¢ = bufto}: System arrayeopy (buf, 1, but, 0, ——Last): GAP CwvritersWatting >'0) > ” notify AIL Qs 50 oan ” up’ cum aji observat, metodele get () si put () au fost ficute mai in- teligente. Ele verifc mai inti daca este necesara vreo notificare (nile 44 si 257 {4 COORDONAREA FIRELOR DE EXECUTIE 69), dupa care utilizeaz not ifyA11() pentru a difuza notificarea la toate firele de execusie aflate in asteptare, 84.7 Utilizarea lui Interruptedzxcept ion Aji observat cu siguranji utilizarea consecventi de-a lungul acestui capitol a clasei InterruptedExcept ion. Daci vefi examina modul in care este declaratii metoda wait () tn clasa Object, vetiinjelege de ce: Public final void wait() throws InterraptedException wait () declard cd ar putea si arunce o Interruptedexception. A- cast exceptie se genereazi atunci cind se apeleaza metoda interrupt () a clasei Thread. Limbajul Java oferi posibilitatea de a intrerupe asteptarea de orice natura (wait, sleep) a unui fir de executie prin generarea unei exceptii de lipul Tnterrupted=xcept ion intrn alt fir de executie, folosind metoda interrupt (). Aceasti metodi este uti aflate fn asteplare in eadrului unui wait (), sleep () sau aaltor operati (de exemplu cite de la un socket) ati pentra a trezi firele de executie Rezumat Este deosebit de important si distingem situaile in care este cazul si se utilizeze mai multe fire de execufie de situaile in care trebuie si le evitim. Cel ‘mai important motiv pentru utilizarea firelor de exeeusie este necesitatea de a realiza mai multe operaii,a ciror rulare amalgamati va produce o utilizare mai ficient a maginii de calcul (incluzsind aici si posibilitatea de a distribui opera fille pe mai multe procesoate) sau va imbunitiiinteraetiunea cu utilizatorul, rea fielor de execufie are si dezavantaje, cum ar fi sc&derea vitezei din cauza asteptirii dupa resurse partajate gi cresterea utlizarii proce- sorului pentru a le gestions, Un alt avantaj important al firelor de executie este ci, aga cum am mentionat la inceputul capitolului, ele inlocuiese schimbiirile de context mari consuma- toare de resurse generate de procese (de ordinul miilor de instrucyiuni) cu schim- bride context rapide (de ordinul sutelor de insteucjiuni). Avand in vedere fap- tul c& toate firele de execuie din cadmul unui proces partajeaz’ aceeasi zon’ de memorie, o schimbare de context nu implica in acest eaz decét modificarea punctului de execute $i a variabilelor locale, Pe de alt& parte, o schimbare de context in cazul proceselor implica interschimbarea intregului spajiu de memo- 258 {4 COORDONAREA FIRELOR DE EXECUTIE Fircle de executie reprezinta o lume nous, iar a inva si le utilizezi este echivalentcu asimilarea unui nou limbaj de programare. Una dintre principalele dificultayi egati de frele de executie este dati de faptul ci’ mai multe fre pot partaja aceleasi resurse, cum ar fi atributele unui obiect, iar in acest ca trebuie sit Vi asigurafi ci nu se poate intimpla ca mai multe fire sa incerce si acceseze resursa in acelagi timp, Accasta presupune utilizarea atent& a cuvantului cheie synchronized, care este o unealtd extrem de utili, dar care trebuie injeleasi in profunzime, deoarece poate si provoace situafii subtle de blocaj circular, Capitolul de fayi este departe de a epuiza toate subiectele legate de firele de execusie. Nu am vorbit aici despre prioritatea fitelor de executie, despre sgruputi de fire de execusie si clasa ThveadGroup sau despre fire de execusie daemon, Veji gisiinformayii despre toate aceste subiecte in excelenta carte a lui Bruce Eckel, Thinking in Java (vezi {Eckel)). Pentru 0 prezentare mai avansat a firelor de executie, consultaji Concurrent Programming in Java, de Doug Lea, Addison-Wesley, 1997. Notiuni fundamentale blocaj circular (deadlock): situate in care dou’ sau mai multe fire de exe- coufie asteapti eliberarea a dou sau mai multe resurse pe care le detin reciproc (deci nu vor fi niciodatt eliberate). coordonare: termen utilizat pentru a desemna dirijarea executici a dou sau ‘mai multe fire de execujie folosind metodele wait () gi notify () fir de executie (thread) : un flux de execujie tn cadrul unui proces. inconsistenfé la concurenfa (race condition): eroare de programare care cauzeazi comportamentul eronat sau imprevizibl al unui program. Mai exact, aceasti eroare apare in cazul in care rezultatul unei operafii depinde de factori temporali imprevizibili, cum ar fi ordinea in care s-a alocat timp penteu execuyia firelor de executic. ‘monitor: obiect special utilizat pentru a realiza excluderea reciproci a unui grup de metode, tajare de resurse: dou’ sau mai multe fie de execujie au acces la ace- leasi resurse (de exemplu, la atributele unui obiect). Proces: program de sine stititor, care dispune de propriul lui spatiu de adrese serializare: consti in a impune accesul unui singur fir de execujie la un ‘moment dat lao resursi in acelagi timp. sineronizare: reprezint& coordonarea unor evenimente astfel incdt doar un anumit eveniment se produce la un moment dat, 259, {4 COORDONAREA FIRELOR DE EXECUTIE Erori freevente 1, Ceamai freeventi eroare este ci programatorul nu este constient ci uleazi intr-un mediu multithreaded (de exemplu in cazul unui servlet Java) si serie cod ignoriind complet inconsistenfele la concurenga. 2. Multi ncepitori definese firele de executie corect, dar uti si Ie pomeasci 3. Din cauza grabei sau a lipsei de experienfi, adeseori nu sunt detectate secvenele de cod care pot conduce la inconsisteng la concureni 4, Nu este suficient s& sincronizém modificatorii unui aribut pentru a objine cconsistenja la concurenta. Trebuie sincronizate si secvengele de cod care acceseazA acelatribut 5, Apelarea metodei wait () pe alt obiect decat cel pe care s-a ficut sin- ‘ronizarea va genera o I1 legalMonitorStateExcept ion. 6. Apelul lui not ify () pe un object pentru a notifica un fir de executie ‘care se afli in asteptare pe un alt obiect, nu va avea nici un efect. Pe scurt 1, Care este diferenja inte fire de execute si procese? 2. Ce interfafi Java trebuie implementatd de cite firele de execusie? 3. Ce metodi este apelata pentnu a porni un fir de executie? 4, Ce metodi este apelati de citre magina virtual la pornirea unui fir de executie? 5. Cand trebuie utilizat cuvantul cheie synchronized? 6. Cand este de preferat instructiunea synchronized () metodelor sin- ‘eronizate? 7. Ce este un monitor? 8, Care este diferenga intre coordonatea gi sincronizarea fitelor de execusie? 260 $4, cooRDONAREA MRELOR DE EXECUTE In practic 1. Creai dowi clase derivate din Thread. Metoda run () a primei clase objine o refering citre cea de-a doua clasi, dupi care apeleazi wait () pe acest obiect. Metoda run () a celei de-a doua clase va apela metoda not fyAl2 () pentru primul fir dupa cateva secunde, astfelincdt acesta i poatd afiga un mesaj 2. Construifioclasti Account Test eare si puniiin evident problemele de inconsistengi la concureni pe care le are clasa Account din paragraful 83.2. 3. Modul in care este implementati metoda get () in clasa Buffer din paragraful 8.4.3 este ineficient, deoarece necesiti deplasarea tuturor ele- ‘mentelor din buffer cdtre stinga (avand astfel complexitatea O(n)). Mo- \ificaji clasa Buffer pentru a refine elementele sub forma unei cozi (etalii despre cozi in volumul al doilea, dedicat structurilor de date gi al- goritmilor) astfel inedt metodele put () si get () si aibiicomplexitatea 000) 4, Clasele Buffert, Consumert si Producer? din paragraful 8.4.5, constituie o implementare a problemei bufTenului cu un singur produci- {or siun singur consumatorin care sineronizarea $i coordonarea firelor de cexecutie este Ficuti in eadrul producatorului si consumatorului. Adaptaji aceasti solujie pentru a funciona si in eazul problemei bufferului cu pro- Settings -> Control Panel; 3. Figienul j2sdk-1_4_0-win exe reprezinti programul de instalare al Java 2 SDK. Rulayi fisicrul si urmaigiinstrucgiunile simple care va sunt furnizate de program; 4, Setali variabila sistem PATH. Setarea variabilei sistem PATH vi per- mite si puteii ula convenabil executablele Java 2 SDK (javac.exe, Java.exe, javadoc .exe etc.) din orice director fied si fie nevoie si Serie Intreaga cale in linia de comand’, Daci nu setati variabila PATH, va trebui si specifica intreaga cale citre executabil de fiecare dati cind dori sit rulayi cain exemplul de mai jos: Tmeabytes Acme tomsi Ia versinnea Kitt Dact afi ales © att versie a kth Java 2 SDK (de employ, 1.30 et), mai mul ca sigur dimensunen fier afi al, rename anterioar versa ale 268 c:>\jdkl.4\bin\javac MyClass. java Peatr a evita o asemenea sntatd incomods, ediugafintreage cle a de rectorulii 3dk1 , \bin In variaila sistem PATH. Dacia instalare afi ties option implicit, calea shook ste c:\jdk1.4\bin Setarea ci se ealizeazidiferit, in fancied versinea Windows pe care 0 fotos = pentra Windows NT, Windows 2000 si Windows XP: apisaji Star, Ser tings, Control Panel, dubla click pe System. in cazul Windows NT, se- lect tabsul Environment; la Windows 2000 seletat tab-ul Advanced si Environment Variables. Apoi, chai variabila sistem PATH tn User Variables sau System Variables. Dac nu suntfi sigur unde anume dori si adiugaicalea citre executabiele Java, adugayi-o la final variable PATH din User Variables, Configurar cit congine calea absolutd a director in care est instalat Java (de exemplu, ¢:\ jak .4\ bin), Seriereaculitere mari sau mici mu are vreo influent, In fina, apasai Se, OK sau Apply. Variabila sistem PATH este o succesiune de directoare separate de ":", Sistemul de operare Windows cauta executbilele Java Gavac, java, javadoc, etc) indretoarele menfionate in cae, pa curgandvariabila PATH dela stinga la deapta. Este important de rejinut cin PATH tebuie save un singur director bin pentru Java SDK laun ‘moment dat (celelaltediretoare de acest fel care urmesia dupa primul, sintignorate). Nous cale are efet in feeare nou fereast Command Prompt pe care o deschieti sa in iecare program pe cae il exeeua de acum inainte (cum a 8 JEAit, Creator et.) = pentmi Windows 98, Windows 95: editaifigienal autoexec.bat (for losind de exemplu Start -> Run sysedit). Ciutai seevenja in care este definti varabila PATA gi adiugai in final calea absolut cite ex- ceutabilele Java, Daci nu exist nici o seven de defnire a varabilei PATH, adiugai-o pe o posite onrecare in fiir. lati un exemplu tpic pentr setarea variable PATH in care se alli exccutabilele Java PATH C:\WINDONS, \WINDOWS\COMMAND; ¢:\Jdk1.4\bin Serierea cu literele mari sau mici nu are nici o influen{i. Pentru ca setarea li sX devin’ functional’, executati urmatoarea instructiune intro fereas- i Command Prompt autoexec.bat 269, |A2.INSTALAREA MEDIULULIAVA Pentru a afla setarea curenti a ctl sau pentru a vedea daca a avut efect schimbarea, tastaji in linia de comand’: cr\> path in acest moment, sistemol dumneavoasra este pregtit pent utlizarea Java 2 SDK. Peni a verifiea acest Iver, exccutaiintran Command Prompt co- manda c:\>java -version Daca instalarea a decurs fir probleme, va fi afigat un scurt mesaj cu date despre versiunea Java instalat&. Dac& primigi un rispuns similar cu: ‘The name specified is not recognized as an internal or external command, operable program or batch file. {nseamnd ci mediul Java nu a fost corect instalat sau variabila PATH nu are © valoare coreet Pentru dezinstalarea Java 2 SDK, folosi Control Panel. incjia Add/Remove Programs din A.2.2 Instalarea sub Linux Java 2 SDK ruleazi de platformele Intel Pentium sau compatible cu ker nel Linux v2.2.12 si glibe v2.1.2-12 sau versiuni mai recente. Aveji nevoie de minim 32 MB RAM de memorie si un spasiu liber pe hard-disk de ‘75MB. Putejiverifica versiunea curenti de g1.Lbe folosind comanda! As /Lib/Libe-* A.22.1 Instructiuni de instalare Pachetul Java 2 SDK, Standard Edition, v1.4.0 este disponibil in dou for- ‘mate de instalare: # Unfisierbinar j2edk-1_4_0-Linux-386 . bin care se autoextrage (autodezarhiveaz’) si astfel Java 2 SDK se poate instala in orice locatie de pe dise. Pentru aceasti metodi, consultaji sectiunea A.2.2.2; « Figierul j2sdk-1_4_0~1inux-i386-rpm. bin care congine pachete tip RPM(Red Hat Package Manager) cu Java 2 SDK. Pentru a instala folosind aceast metoda, consultaji sectiunea A.2.2.3. 270 [A2. INSTALAREA MEDIULULIAVA erele pentru ambele formate de instalare sunt cuprinse in cadrul unui fisier shell scx ipt . bin care afigeaza licenja inainte de a incepe instalarea. A222 Instalare cu autoextragere Pentru instalare, executayi pasii urmator: 1. Verificayi dimensiunea figierului j2sdk~1_4_0~Linux-i386.bin, (0 dimensiune de 40618207 bytes indict © desearcare corecti a kitului de instalare. Dacii mirimea fisierului nu corespunde celei de mai sus, {nseamnd ci fisierul a fost deteriorat in timpul descarcirii, Singura alter nativieste de a incerca din nou descircarea figieruluis 2. Copiaji j2sdk—1_4_0-1inux-i386.. bin ndirectoral in care dori si instalai Java 2 SDK; 3. Rulaji 32sak-1_4_¢ chmod atx j2sdk-1_4_0-linux-i386.bin -/J2edk-1_4_0-linux-i386.bin Scriptul de instalare va afiga 0 licen de utlizare, dupa care, daca accep {afi condigile expuse in licen’, Java 2 SDK se instaleaz4 in directorul ccurent; 4. Adiugayi calea absoluti citre directorul bin rezultat in urma instalarit (deexemplu, /usx/loca/ jdkt. 4/bin) variable’ sistem PATE. A- ‘cest lucru se poate face astfel, functie de shell-ul pe care il ut = pentru esh sau tesh: % set PAT SPATH/usr/local/jdk1.4/bin) + pentru sh % PATHs($PATH/usr/local/jdk1.4/bin); export SPATH Puteji si addugayilinile anterioare la sfissitulfisirelor .pro£ile sau eshre pentru a nu le mai scrie la fiecare login-are. Pentru a verifica dacd instalarea a decurs fra probleme, deschideti o consold si tastayi comanda: java -version 2m |A2.INSTALAREA MEDIULULIAVA acl nu au fost semnalate erori pe parcursul procesului, atunci vei vedea tun mesaj cu detalii despre versiunea Java instalaté. Dac& primigi ispunsul: java: Command not found ‘sau ceva similar, atunci mediul Java nu a fost bine instalat sau variabila PATH nu are 0 valoare corecti, A.2.2.3 Instalarea folosind RPM 1. Verificayifisicrul j25dk~1_4_0-1inux-i386—rpm. bin. Odimen- siune de 39482030 bytes indica o descarcare corectaa kitului de instalae. Dacit marimea fisierului nu corespunde celei de mai sus, inseamna 8 fisierul a fost deteriorat in timpul descareari, incercati din nou si dest cali figierul respectiv; 2, Rulayi j2sdk~ 4_0-Linux-i386-pm. bin folosind comenzite: chmod atx j2sdk-1_4_0-Linux-i386-rpm.bin -/§28dk- 1 inux-i386-rpm. bin Scriptul va afiga o licenga de uilizare, dupa care, daca acceptajicerinjele licenjei, vefi objine ca rezultat j2sdk-1_4_0~1inux-i386.rpm, fisierce va fi creat in directorul curent; 3. Accesati sistemul ca root folosind comanda su gi parola acestui cont: su - root 4 Dezinstalai J2SDK 1.4.0 Beta (in cazul in care exist aceast versiune anterioari deja instalati pe ealeulatorul dumneavoast) Nout: Calea implicit pentru instalarea RPM a lui J2SDK este urmi- toarea: /usr/java/j2sdk1.4.0. Acesta este director in care au fost instalate si pre-release'-usile versiuni 4 (in cazul in care acestea au fostinstalte). Pentru a pregati instlarea versiunii finale, i acest director copy todir="bin"> * include: * properties"/> fn acest exemplu,scopul compile copia fierce .properties (de exempla. jnds .properties) in directonil bin gi apoi compileazs toate clasele din drectonul sz in directonul bin, pastrind strctura de directore. Scopullbu$ 1d depinde de scopul comp’ Le, decicdnd se lanseazi ant. build, mai ini se executiscopul compe i dach mu apare nic oeroare se execut Scoptl build, Scopul build aiveazi fgirele din directonal bin intro ‘thi de tp jar numiti MyComplexapp.. jar. Prezentarea Ant din cadrul acestui paragraf este mai mult det sumari, rolu i find doar de a vi deschide apetitul pentru procesaea automat, Mai mule detali pute afla la adresa http: //Jakarta. apache .org/ant 276 A4 Rularea unei aplicatii java Executia unei aplicagi Java implicdexistenja (pe Hinga bibliotcile foloste de aplicaye) unei masini virutale Java sia bibliotecilor standard (care congin clasele java.lang.*, java-util.*, java.io. etc.). Acestea sunt incluse in SDK-uri si JRE-uri Java Runtime Environment), Pentru a rula 0 aplicayie Java este sufcient un JRE (mediu de execuic Java) care, spre deoscbire de SDK, mu confine utilitarele pentru dezvoltarea programelor (de exemplu, Javac), ci doar pe cole nocesare execute lor. Este necesar s8 clarified nigle denumiri, Pan la aparijia versiunit 1.2 a IDK.-ului (Java Development Kit), denumires Java 2 Platform Standard Edition (SE) nu a existat. Incepaind cu acea versiune, a apirut Java 2 Platform Stan- dard Eston ou SDK. 1.2 (Standard Development Kit) In continuare a SDK 1.3 i SDK 1.4 care fin tot de Java 2 Platform Standard Edition. Revenind, pentru rulade exempla Primu1Program. class sefoloseste comanda urmitoare, executati in directorl eurent java PrimulProgram AAI CLASSPATH Bibliotecile necesare rulirii unei aplicatii (eu excepfia bibliotecilor stan- dard) trebuie incluse in variabila sistem CLASSPATH (aga cum am descris in parageaful A.2) sau pot fi specificate in linia de comand, folosind optiunea “classpath . Utlitarele din SDK folosese urmatoarea ordine pentru a cua 0 clas: # clasele din / jre/1ib/rt . jaz,urmate apoi de clasele din arhiva /jre/Lib/i18n. jar; «© clasele din /jre/1ib/ext/*. jar «© clasele din variabila CLASSPATH. De exemplu dact este cfutati clasa MyClass din pachetul com.mypackage si variabila CLASSPATH are valoarea /root /work/server_upload/:/usr/local/jars/xerces. jar, atunci figierul MyClass. class vafi clutatastfl: 1. inathivele din jre/1b; 2. indirectonul /root /work/server_upload/com/mypackage/; 27 [AS DOCUMENTATIJAVA 3. imathiva /usr/local/jars/xerces. jar,subdirectorul com/my- package/. AS Documentatii java Principala sursi de documentare pentru limbajul Java este siteul oficial al ‘companiei Sun Microsystems: java. sun.com, Documentatia Java 2 Platform Standard Edition se gaseste a adresa de In- temet: http: //java.sun.com/j2se/1.4/docs. Acolo poate fi gist si functionalitatea bibliotecilor standard (APD), Pentru a genera documentajii in format HTML din fisiere sursi Java, se foloseste utilitarul javadoc, 28 B. Conventii de notatie in Java. Uti- litarul javadoc fn Mandstire existau anumite lar Macstrl ne- ras Jnotdeauna aenjia asupratiranei regulilor. “Anthony de Mello, O clip de ingelepciune fnceputel injlepciuni consti in a ddesemna obiectele eu namele lor adecvate Proverb chinzesexe Femele gi pisicle vor face Inotdeauna ceea ce vor, iar birbafi si ini trcbuie si se relaxeze si si se impace eu idee, Robert Ac Heinlein B.1_Necesitatea conventiilor de scriere a programelor Convengile de seriere sunt foarte importante pentru programatori din mai multe motive: * Conform studiilor de speciaitate, 80% din costul unei aplicafii software ‘este datorat intrefineri aplicaiei respective; 279 5.2, TIPURI DE PSIERE + Este foarte pujin probabil ca aplicagia st fe intreyinuti pe intreg parcursul cexistenjei ei doarde citre cei care au dezvoltat-o; # Conveniile de notajie imbunstajesc lizibilitatea codului, permitind pro- ‘gramatorilor i injeleaga codul nou mai rapid si mai profun «# Daca aplicaja scrisi de dumneavoastri este distribuitd ca produs, trebuie Si vi asiguragi ci este bine realizata i organizati. Exist deci motive foarte fntemeiate pentru a utiliza convenile de seriere a pro- ‘gramelor. Probabil ci cititorii vor observa faptul ci uneori aceste convengii nu ‘au fost respectate pe parcursul lucririi, Situajia este explicabild prin faptul c& spatiul disponibil a fost limitat,ceea ce a condus la evitarea utlizarii conven ilor mai “costisitoare” din punct de vedere al spajiuluitipografic (de exemplu, abundenja de comentarii javadoc). Totusi, sugestia nostri este s& nu evita folosirea acestor convengiiin programele dumneavoastea, indiferent de marimea sicomplexitates aplicatilor. B.2_ Tipuri de fisiere Java foloseste urmitoarele extensii pentru figiere: ©. Java, pentns fisiere surss © class, pentna fisiere compilate (bytecode) Daci exist mai multe figiere intr-un director, atunci este benefic& prezenja unui figier README, care s& deserie conyinutul directonului, B.3 Organizarea fisierelor sursé . java Un fisier sursit este impuiryt pe sectiuni separate prin linii goal gi, optional, uun comentariu ce identified fiecare secfiune. Fisierele eu peste 2.000 de linit sant incomod de parcurs si modificat $i webuie pe cat posibil evitate. Vom prezenta un exemplu elocvent de progeam Java formatat in mod corespunzitor {in paragraful B.10. Fiecare fisier sursi Java congine o singurd clasi public’ sau interfaya. Cand clasa public& este asociaté cu alte clase sau interfeje ne-publice acestea se pot serie in acelagifisier sursi cu clasa public, dar clasa publica trebuie si fie prima in cadrul fsierutui. ‘Secfiunile unui figiersursi Java sunt: 280 1.3. ORGANIZAREA FISIERELOR SURSA .78VR © comentariile de inceput; « instrucjiunile package gi import ; © declaratile claseisi/sau interfeei B.3.1 Comentariile de inceput Consin informayii legate de copyright si o descriere a fsierulu. Informatia copyright are urmatorul format standard ra ) 4 This file contains proprietary information of 1 + Copying or reproduction without prior written 2 t approval is prohibited © # Copyright (c) xxxex Descrierea fisierului congine observa legate de numele figierului, functio- nalitatea lui, modul de utilizare a claselor sau interfefelor care il compun gi alte informayii adiionale, Comentariul trebuie si fie in stil javadoc (informa detaliate despre utlitarul javadoc in paragraful B11): ie f+ File mame: Salut. java S Description = program ce afireaza am salut de bun venit ae in lumee Java. Contine clasele 3 t Usage : standard (eva Salut) tt Version: 1-0 +t Dare: 15 lanuarle 2002 ta B3.2_ Instructiunile package gi import ‘Numele pachetului trebuie si apari pe prima linie necomentat& din figieral sursi si rebuie si respecte convengia de notare stabilitd in aceasti anexi. T- ‘mediat dupa aceasta, trebuie si apari declaratile de import ale claselor. De exemplu: ‘package test capitoluls Himport java awt. Graphics: ‘import java util + 281 13 ORGANIZAREA PSIERELOR SURSA vA B33 Declaratile clasei si interfetei clastlinterfayttrebuie si fle declarattastfel (exact in aceasttordine): 1, comentariul de tip javadoc (/** */),in care se precizeaza informatii publice despre clasi/interfat; 2, cuvamtul cheie class sau interface, urmat de numele claseis 3. optional, comentariu legat de implementarea clasei/interfejei (/* * /). Conyine informayi private, nenecesare pentru utilitarul javadoc; 4, atributele static. Mai inti cele publ ic, apoi cele protected, cele {irk modificatori de acces gi, in final, cele private. Evident, in catego ria atributelorstatice intra si constantele; ‘5. atributele nestatice, in aceeasi precedentiica gi cele statice; 6, constructor clase’ 7. metodele clasei. Metodele trebuie grupate din punt de vedere al func Jionalitayi, si nu din punct de vedere al accesibilitiii. De exemplu, 0 ‘metodi stack privatd s-ar putea aflaintre dou metode nestatice publice. Scopul este de a face codul cit mai usor de citi ingeles. Fiecare metod este precedati de o descriere precisi in format javadoc. Documentatea este obligatorie pentru metodele publice. Metodele standard de acces la atribute (metodele de tipul get /set) pot fi grupate firl a avea © descriere, funcfionalitatea lor fiind binecunoscuta (modifica sau returnexzi valoarea unui atribut al clasei). Standardul stabilit pentru descrierea metodelor «este realizat in aga fel incdt descrierea si fie ugor de infeles. Multe elemente sunt ‘optionale gi pot fi omise, Fiecare element de pe linie incepe cu simbolul asterisk (*) si se termina cu spajiu, Dacd un element este prezentat pe mai multe lini, atunci fiecare linie incepdnd cu a doua trebuie indentat astfel ined fiecare line sii fie aliniata vertical eu cea precedent, ‘Un exempl araté astfel thee bt edeseriere detatlara a metodel> 0 a Serplicarca tipetui de waloase returnat> ft @exception — +t @author Shumeleautorulul> we Cavintele @param, @return, @except ion, @author reprezinta le recunoscute de javadoc (paragraful B.11), Deserierea detaliat a metodei trebuie si cuprind # rolul metodei «© pre si post-condi «© efecte secundare; dependente de alte metode/clase; ce alti metoda ar trebui si apeleze aceast metod’; + daci metoda trebuie sau nu si fle edefinita in clasele derivate. Secjiunea ¢param descr tipul,clasa, constringerile tuturor argumentelor me- todei, De exemplu: * @param —strSursa ~ stringul de intrare Nu poate fi de dimensiune 0 Secjiunea @return descrie valoarea retumatii de metodi: tipul de date returnat, domeniul de valori in care se poate afla valoarea returmati gi, daci este posibil, informaja de eroare returnati de metoda. De exemplu: *@return returneaza un intreg din multimea 1..n. Sectiunea excepjiiloroferi o descrierea excepiiilorpe care metoda le arunct. De exemplu, * @exception ResourceNotFoundException - daca resursa nu a fost gasita. Desi este evident, adugim un exemplu gi pentru sectiunea autor: * @author Mihai Tonescu B.4_ Indentarea Codul sursi trebuie si fie indentat, folosind fab-uti si nu spatii, Indentarea cu tab-uri are avantajul c& in aproape toate editoarele de texte se poate modi- fica nivelul de indentare selectind dimensiunea preferati pentru caracterul ta, Aceasta este in general seta la doua (2) spafi, dar se considera acceptabil si tun tab de patra (4) spati. 283 B.4.1 Lungimea unei linii de cod ‘Trebuie evitatelinile de cod mai lungi de 80 de caractere, pentru cf nu pot fi tratate corect de anumite terminale si editoare. De asemenea, lniile care aleatuiese comentariul javadoc nu trebuie si depigeascl 70 de caractere, B.4.2_ "Ruperea" liniilor fn siuafia in care o anumitiexpresie nu este total vizibili pe ecran (are 0 lungime prea mare, est indicat "ruperea” ei, penta ca fot cod surs si fe viaibil, fed si fle nevoie de serol-areaorizontali a figierului. Regulile dupa care se realizeazi aceasta operajie sunt urmatoarele: «“rupere” dopo vinguls «© “rupere” inaintea unui operator; « alinierea liniei noi cu inceputul expresiei la acelasi nivel cu li dent’; rece: ‘© dacd lniile de cod sunt confuze, indentafiliniile noi cu 1-2 tab-uri. De exemplu: " mumeLungl = numeLung? + (numeLung’ + numeLungs ~ numeLungs) zl be mumeLuag6: //ASA Da ‘numeLungl = numeLung? + (numeLung3 + oumeLungs ~ : fnomeLungS) +4 + mumeLung6; //ASA NU B43 Acoladele Acolada de deschidere trebuie si fie pe linia urmatoare,aliniaté vertical cu linia precendenta. Acolada de inchidere trebuie si fe peo linieseparat aliniata cu acolada de deschidere Exempla: et (conditie) Este acceptati gi deschiderea acoladei pe aceeasi linie cu ultima instructi- une, si inchiderea aliniaté vertical cu instrucjiunea care a deschis acolada: 284 HIF Cconditien| a ‘Alegerea uneia dintre cele dows variante este o chestiune de preferingl per- sonali, Prima are avantajul de a creste liziblitatea, dar unii se plang e& ocup’ prea mult spafiu, Dupi cum afi observat studiind codul din aceasta Iuerare, tori preferk si utilizeze prima variant. B44 Spatierea Liniile goale plasate adeevat pot imbunitii liibilitatea codului, imparyind codul in secjiuni logice. Douii lini vide trebuie folosite in urmioarele circumstante: «© fntre secjiunile unui fisiersurs8; «© intre definirile claselor si imterfejelor. O linie vidi trebuie folositi in urmitoarele situaii: « fintre metode; ima sa instructiune; + inaintea unui comentariu de tip bloe sau a unui comentariu pe o singuri Tinie (veri seetiunea 5.1 din prezenta anes Spatile trebuie folosite in urmatoarele situa + un cuvantcheie urmat de o parantezi trebuie separat prin spajiu de aceasta Exemplu: wh 3 a (tre) ‘Trebuie reyinut faptul c& spayiul nu este interpretat ca separator de care ‘compilatorul Java atunci cind se afl intre numele unei metode si paran- teza care deschide lista de argumente a metodei; «un spafiu trebuie si apard dupa virgul (, ) in lista de argumente; 285 «© toi operatorii binari, cu excepfia punctului (.) trebuie separaji de ope~ ranzi prin spasiu. Spaile nu se folosese niciodata pentru a separa opera torii unari si cei de incrementare/decrementare (++ /—). De exemplu: ras (beeys (ate): sbees sprintSize(a, b, ¢): + expresiile dint-o instructiune for trebuie separate prin spajiu. De exem- pl: for (expr: expr2: expr3) © operatorul de cast trebuie tot timpul urmat de spagiu: imyMethod (byte) uaNumar, (Object) x)5 B.S Comentariile Programele Java pot avea dou tipuri de comentari: comentarii de imple- mentare si comentari pentru documentajie. Comentariile de implementare sunt de tipul celor din C+#, delimitate prin /*...*/ sau //. Comentarile pentru documentatie, cunoscute sub numele de comentarii javadoc, sunt disponibile doar in Java si sunt delimitate de /**. . .*/. Comentariile javadoc pot fi cextrase gi formatate fn fisiere HTML folosind aplicaja utilitard javadoc. Comentarile de implementare adue clarificiri asupra codului sursi si sunt adresate programatorilor care Iuereaza sau vor lucra la serierea codului. Co mentariile de documentajie aduc clavificari asupra rolului fieciei clase, inter- fle, metode ete. si sunt adresate celor care dorese si utilizeze clasele serise de noi, fra afi interesayi de detaiile de implementare (codul surs8). Comentarile conjin doar informaiirelevante pentru citiea si injelegerea programului. in general, este bine si se evite duplicarea informajiei care este prezentati intro forms clard in interionul codului. De asemenea, este bine si se evite comentarii care ar putea deveni neactuale pe mésuri ce codul sursi ‘evolueaza. Pe de alté parte, comentariile nu trebuie si fie folosite in mod abuziv. Freevenja mare a comentariilor reflecti uneori o calitate slab a codului. Dac simaiji nevoia si comentaji foarte des codul, este cazul s& luafi in considerare rescrierea lui pentru a-l face mai clar. 286 BS. COMENTARILE B.5.1 Comentarii de implementare Programele pot avea patra stiluri de comentarii de implementare: in bloc, peo singusi linie, comentarii de tip rrailing si comentari de tip sfsit de line, # Comentari de tipul bloe Comentarile de tipul bloc sunt folosite pentru. oferi descrier ale fisierelor, metodelor, structurilor de date gi algoritmilor, Ele pot fi folosite la in- ceputul fiecdnui figier si inainte de fiecare metoda. Dacii sunt folosite in interiorul unei metode, comentarile de tipul bloc trebuie sa fie indentate pe acelasi nivel cu eodul sursi pe care il descriu Exemplu: 24 Acesia este un comentaria de tip bloc Comentari pe o singur inie ‘Comentariile mai seurte pot si apara pe o singur lini, indentaté la nivelul codului care urmeaz. Dacii nu poate fi scris pe o singuri linie, comen- tariul trebuie transformat inte-un comentariu de tip bloe. Exemplu: It (conditie) ‘ > fe Trateata cazul cand conditia este adevarata. +/ © Comentarii de tipul trating Comentarile foarte scurte pot si apari pe aceeasi linie cu codul pe care {i descriu, dar trebuie si fie indentate mai mult pentru a le separa de cod. ‘Toate comentatiile de acest tip care apar intr-o porjiune de cod trebuie si aibe aceeasi indentare Exemplu: sit (a 222) at 5 return true: fe caz special, 2 este prim «/ “ pelue “ + return isPrime(a): /* verifica daca a este prime/ "1 287 # Comentari de tipul sfirsit de linie Delimitatoral // comenteazi o linie complet sau paral. Exemplu: 81 (imyAge > 1) a 1 exeeuta 0 operatic B.5.2_ Comentariile de documentatie Platforma Java oferd o aplicajie uilitar, denumiti javadoc, foarte uti- lizatd in crearea de documenta pentru pachetele gi clasele Java. Practic, aceasti aplicayie aimpus un standard in materie de documentare a programelor. Comen- tariile de documentajie descriu clasele, interfefele, constructorii, metodele gi atributele, Fiecare astfel de comentariu se giseste inte delimitatorii/**. ..*/, cu specificatia ed existé céte un singur comentariu pentru fiecare clas, interfajd sau membru al clase _Exemplu de comentariu de documentatic: thee 1+ Clasa Vehicle ofera ‘public class Vehicle a ” Comentarile de documentayie nu trebuie pozifionate in cadnul vreunei meto- de sau constructor, pentru ci Java asociazii aceste comentariicu prima declarare de metodi pe care o intilneste dupa comentariu, Aminunte despre modul de utilizare javadoc sunt prezentate in paragraful B.11. B.6 Declarari B.6.1_ Numérul de declarari pe linie Se recomandi folosirea unei singure declariri de variabilé pe o line, deoa- rece astfel se incurajeazii comentarea linilor respective. De exemplu, varianta Int i: // indicele sirulut int dim; //" dimensiunea sirutui 288 este preferata variantei int i, dims B.6.2_ Initializarea variabilelor Este indicat ca initiaizarea variabilelor si se facd in momentul declarii Exist situajii in care acest lucru nu este posibil, de exemplu cind valoarea initial a variabilei depinde de anumite calcule care trebuie mai intai efectuat. B.6.3. Locul de declarare a variabilelor Cel mai bine este ea declarasiile variabilelor si fie realizate la inceputul blocului in care sunt folosite (un bloc este delimitat de acolade {}), pentru a evita posibilele confuzii de nota. B.6.4 Declararea claselor si a interfetelor Incarul declare clase sau interfef trbuierespecate urmitoarele regi de formatae © nu existi spajiu fntre numele metodei gi paranteza " (* cu care incepe lista de paramets; metodele sunt despiite print-olinie vids Exemplu: selass Test ot S) vold firstMethod () oo eo t yoid second Method () 7 4 sy 289 28. INSTRUCTION B.7__ Instruet B.7.1 _ Instructiuni simple Pentru claritate, fiecare linie trebuie si congina cel mult o instrucjiune. Ten- dinga generalé a progeamatorilor incepitori de a scrie mai multe instrucjiuni Pe o singuri linie, pentu ca astfel programele si par mai “miei este puerilt si nejustificata. Un program aersit, in care instructiunile se sueced una sub cealalta este mult mai ugor de parcurs gi de infeles decat un program imbacsit gi Inghesuit, chiar daca acesta este de trei oi mai scurt sarge 445 //ASA DA pages //ASA DA argy +45 arge~—i //ASA MU B.7.2_Instruetiuni compuse Instructiunile compuse reprezinti o lista de instructiuni cupr lade () « instrucjiunile compuse se indenteaza cu un le compune: el fay de instrucjiunea care Vif (congitie) st + instructiune_indentats_cu_un_nivel la de deschidere trebuie si fie pe o Tinie noud aliniatt vertical cu Tinia precedent, iar acolada de inchidere trebuie si fle pe o linie now’, init vertical cu acolada de deschidere: st (conditie) f1 Malintere verticala eu instructiunea 1] Maliniere verticala cu acolada de deschidere # acoladele trebuie folosite pent toate instructiunile, chiar gi penta o sin- gurd instructiune, atunci cand fac parte dintr-o structur& de tipul if-else sau Fox. Astfel este mai simplu de adaugatinstructiuni, fr% a genera ac~ Numele link-uluic /a>, afigea- ziun link HTML 304 1 UTILITARUL vavADOe © @see pachet.clasafmembru numeLink, afgeazi un link HTML céitre documentajia generat pentru membrul care apartine clasei din pa- chotul specificat @s ince afigeaza un text care indicd versiunea aplicafiel software care a prezen- ‘at pentru prima dati elementul respectiv. De exemplu, @since 1.3 denoti faptul eX elementul a aparut in versiunea 1.3 a aplicaie. Gversion este utilizat in general cu argumentul "8%, ¥G%", care este convertit de javadoc in ceva similar cu "1.39, 02/28/99" (lunalzi/an), adicd versiunea si data trecerii la versiunea respectiv. {@link pachet.clasa#membru numeLink} se aseamini cu eti- cheta @see, cu deosebirea ci link-ul creat nu este afigat in sectiunea See also, javadoe -sourcepath c:\user\sre com.mypackage -classpath listacaiClase Este specificati calea unde javadoc va cata clasele eferite (pentru detalii despre claselereferite, vezi secjiunile anterioare din aceasta anexa), ~Joptiune Lanseaziicomanda java cu opfiunea specificati de argumentul opt dune. De exemplu, pentru aflarea versiunii utilizate de javadoc, se executt co- manda: c:\> javadoc -J-version Trebuie refinut faptul ci nu exist nici un spatiu intre opfiunea J si argu- mentul opt dune. Opfiunile prezentate anterior pot fi uilizate de javadoc indiferent de doclet- ul folosit in generarea documentajiei. Implicit, javadoc utilizeazi doclet-ul standard, care genereazii documentatie in format BTML. Acest doclet oferi un alt set de opyiuni, care vine in completarea celui anterior. Tat8 citeva dintre aceste opyiuni: Este specificat directorul destinajie, unde javadoc va salva documentatia HTML generatd, Dac& aceasti opyiune nu este prezenta, atunci documentatia va fi creat in directorul curent. ~version Include textul asociat cu eticheta @ver sion in documentayia BTML gene- ri -author Include textul asociat cueticheta @aut hor in documentalia HTML generat -splitindex {impart alfaetic sierul de index al documenta vial entra feeae liter. swindowtitie text ste specifica itl cae va plasat in tag-ul din WTI (denami- rea feresrei browser-uli). Acest tly devine ttl ferestrei de browser, viibit in coll din stinga sus ol fereste ~doctitie text Este specifica ital document -neader text Este specificattextul care vaf plasat la inceputul fcc isier de docu- rmentaie generat 306 in mai multe figiere, te -footer text Este specificat textul care va apiiea in dreapta meniului de navigare din josul paginii, “bottom text Este specificat textul care va apiirea la finalul fiecinuifisier generat. in ge- neral, aceste note de subsol contin informatii legate de copyright. -nodeprecated Elementele demodate (pachete, clase, membrii etc.) sunt omise la generarea documentaici. B.11.5 Exemple Vom prezenta in final citeva exemple simple de folosire a utilitarului java~ doc. Utilitanul poate fi rulat pe clase individuale sau pe pacheteintregi de clase. ple de utilizare javadoc + Crearea documentajiei pentru unul sau mai multe pachete Pentru a documenta un pachet, fisierele sursi din acel pacher trebuie si ‘existe intrun director cu acelasi nume ea si pachetul. Daci pachetul este creat din mai multe nume, separate prin simbolul punet (.),flecare rnume reprezint& un director diferit. Astfel, toate clasele din pachetul java. awt tebuie si existe in directorul java\awt\, Presupunem c¥ directorul c: \home\src\ java\awt\ este directorul fn care sunt create fisierele sursi iar directorul destinajie pentru docu- ‘mentatia generat este c: \home\htm1. Vom pistra aceast conventie pentru toate exemplele de acest gen din anexa curenti, Documentajia se poate crea in dou’ moduri: = din directoral corespunzitor pachetului c:\> ed c:\home\sre i> Javadoc -d c:\home\ntml java.awe = din orice director: c:\> javadoc -a home\htm1 -sourcepath c:\home\sre java.awt, © Crearea documentajiei pentra una sau mai multe clase ‘Analog cazului 1, avem dou modalitaji dispon 307 un, UTILITARULJavaBo = din directorul eu figiere surst: \> cd c:\home\sre\java\awt c:> javadoc -d c:\home\html Canvas. java Graphics*. java ‘Se genereaz documentajia pentru clasa Canvas $i pentru toate clasele al c&ror nume incepe cu Graphics. Documentul HTML ‘generat nu va mai avea tri frame-urica in cazul pachetelor, ci dou deoarece generarea s-arealizat pe clase gi nu pe pachete, situ care al trea frame (cel cu listarea pachetelor) este inuti = din orice director: €:\> javadoc ~d c:\home\htm1 nome\src\ java\awt \Canvas. java nome\src\ java\awt \Graphics*. java © Crearea documentajiei pentru pachete si clase simultan ‘Combinarea celor dou’ cazuri descrise anterior, conduce la: > javadoc -d c:\home\html ~sourcepath c:\home\sre java.awt c:\home\sre\Java\applet \Applet. java © Crearea documenta prin specificarea in linie de comanda a um sier Pentru a scurta sau simplifica o comand javadoc, se pot specifica unul sau mai multe figiere care conjin separai nume de fisiere sursi sau pa cchete, cite unul pe Tinie. La execugia comens precedat de simbolul @ numele figierelor trebuie De exemplu, fie figientl packages, cu urmatorul co com.package1 com.package2 com.package3 Se poate rula javadoc astfel (apidocs reprezinti numele directorului de destinatie al documentajiei generate, iar home \sr-c constituie direc- torul in care se aflafisierul packages, dar si directorul com, cu subdi- rectoarele packagel, package2, package3): 1 UTILITARUL vavADOe c:\> ed c:\home\sre :> javadoc -d apidocs @packages * Salvarea mesajelor de eroare generate de executia javado separat (valabil doar pe Windows NT) un fisier Pentru a redirecta eventualele mesaje de eroare generate de execusia comen- zii javadoc, se poate utiliza comanda: c:\> javadoc -d docs java.lang >log.std 2>1og.err sau, forma restransé c:\> javadoc -d docs java.lang >javadoc.log 2>41 Prima variantd redirectioneazi mesajele standard in figierul Log. std, iar pe cele de eroare in Log. err, in timp ce in al doilea eaz, ambele tipuri de mesaje sunt redirectionate catre fgieral javadoc . 103. © Utilizarea din alte programe a comenzii javadoc Se poate folosi o secventi de cod de genul: void metoda() String (I javadocArguments sourcepat! home\ se ‘e:\home\ hemi”, javasawt i ‘com.sun tools javadoc. Main. main javadoeArguments ) hn Heontinuare cod ” Dezavantajul unei astfel de utilizari este ci metoda main nu retumeazi nimic, de aceea nu se poate determina dac& javadoc s-a executat cu 309 C. Definirea pachetelor Java. Arhive jar ‘Simpliicayilucurile att ct ete posibil, dar nu mai mult ‘Alber Einstein C.1_ Prezentare generali a pachetelor Java prede- finite Mediu de programare Java oferi o serie de clase predefinite pentru a veni {n intimpinarea programatorilor care dorese si realizeze aplicafii la standarde peofesionale. Scopul pentru care aceste clase au fost implementate de creator Timbajului Java, a fost acela de a ugura pe cat posibil munca programatorilor, ‘care nu mai sunt obligaji in acest fel "si reinventeze roata", Programatori fo- lsese aceste clase, dar isi pot defini pe baza lor si proprile lor clase, specifice aplicailor pe care le realizeaza Mulsimea claselor oferite de limbajul Java poarti numele de Java 2 API (Ap- plication Programming Interface). API-ul Java ofera facilitii foarte puternice, des utilizate de programatori. Putem spune cu certitudine cé orice program Java utiizeaza din abundenja API-ul Java, Dat find importanga lui, este evident 8 documentajia API-ului capata si ea 0 insemnatate deosebits. Documentayia Poarti numele Java 2 API Specification i poate fi gisita in cadrul documentajiei SDK, Pentru o mai bun organizare, clasele oferite de limbajul Java au fost im- parte in pachete, avand drept criteriu de departajare funcjionalitatea oferits Platforma Java este deosebit de solida gi ofera diverse facilitgi in diferite di- 310 i, cum ar fi applet-uri, aplicajii de tip desktop folosind AWT, apli Swing bazate pe JFC, RMI (Remote Method Invocation), securizarea aplicaji- los, utlizarea bazelor de date, internasionalizarea aplicayilor, crearea de arhive JAR $i ZIP, suport pentru CORBA, etc. Multitudinea de direct in care s-a dez= voltat Java este observabila si in numarul mare de pachete pe care il pune la ispozitia programatorilor: peste 70 de pachete. Numarul este impresionant si devine evident faptul c’ nu putem prezenta informatii despre fiecare pachet parte, Totus in cele ce urmeaz vom descrie cel mai des utilizate pachete, ‘impreuni cu cateva dintre cele mai reprezentative clase confinute. Tati o listi a celor mai des ulilizate pachete (in cadrul acestei Iucriri sunt folosite doar clase din eadnal primelor cinei pachete) # java. Lang, care oferi clase fundamentale pentr limbajul Java; # java.util confine clase pentru utlizarea colectiilor, pentru manevra- rea datelor calendaristice si a timpului, pentru internajionalizarea apli- catilor ete; # java.io, care oferi modalitii de citie/scriere a datelor prin inter- ‘mediul fluxurilor de date, a serializiri sau a figierelor, © java.math, care oferi clase specializate in calcul matematic; # java. text, care oferi clase pentru manevrarea textului, a datelor ca- Jendaristice, a timpului gi a mesajelor intr-o maniery independent de limba utiliza, fie ea englezd, francez, romani etc.; are pune la dispozitia programatorilor clase pentru imple- ajiilor de rejea; © java.net, ‘mentarea ap # java.util. jar, care oferd clase pentni citirea si scrierea fisierelor in format JAR (Java Archive), bazat pe formatul standard ZIP; # java.util. zip, care ofert clase pentru cititea si scrierea de athive in format ZIP sau GZIP. Tati gi céteva dintre cele mai reprezentative clase pentru fecare dintre aceste pachete: © java.tang ~ Boolean, Byte, Character, Double, Float, Integer, Long, Short asociate tipurilor primitive respective: byte, char, double ete. ai = Math, asiguri realizarea unor operaii aritmetice elementare: mo- dalul, functittrigonometrice, exponentiale, maximul si minimul a dou numere, aproximari ete.; = String, StringBuffer, pentru administrarea girurilor de ca- ractere: = System, oferi facilitji de acces la fuxurile standard de intrare Gin), iesire (out) si eroare (err) ete. ~ Thread, asiguri facilitafi pentru luerul cu fire de execute in Java, # java.uti2 Calendar, pentru administrarea datelor calendaristice; Date, reprezinti o dati calendaristict in timp, cu precizie la nivel de miliseeunde; Hashtable, pentru reprezentarea tabelelor de repartizare;, LinkedL ist, pentru administrarealistelor inkinquite; Locale, pentru reprezentarea unei zone politice, geografice sau culturale; ListResourceBundle, PropertyResourceBundlesai Re- sourceBundle, pentru reprezentarea colectiilor de resurse; format LIFO, Lastin- = Stack, pentru administrareaunei stive list FirstOut); ~ Vector, implementeaza un sir de obiecte de dimensiune variabill * java.io BufferedReader, citeste text de la un flux de intrare a datelor, depundnd informagia cititi intr-un buffer pentru a realiza o citire ficient a caracterelor, siurilor, stringurilor; ~ Buf fereditriter, serie text citre un flux de iesire a datelor, de anand informajia scrisi intr-un buffer pentru a realiza 0 seriere eficientd a caracterelor,siurilor, stringurilor; ~ File, care asigurl gestionarea figierelor, inclusiv a locatilor unde acestea se pasesc; ~ FileInput Stream, asigur’ citirea de date sub forma unor gira de bytes dintr-un fsier spes ~ FileOutputstream, asigur scrierea de siruri de bytes intr-un figier specificat; * java-math ~ Bigbecimal, Bigtnteger, care permitcalcululcu numere foar- te mari, care nu ar “incape" in reprezentarea obisnuita a numerelor fn Java, © java.text = ChoiceFormat, permite atasarea de formate de mesaje in funcjie de diverse valor ale unor variable: = DateFormat, asigurd formatarea datelor calendaristce gi a tim- pului int-o maniera independent de limba uilizati; = MessageFormat, permite formatarea mesajelor independent de mb, = NumberFormat, permite formatarea numerelor, a procentelor gia sumelor de bani independent de limba, * java.net = HttpURLConnect ion, oferi faciltii pentru conectarea prin re- {ea laun server HTTP gi adresarea unei cereri serverului respectiv; ~ InetAddress, pentru administrarea unei adrese IP (Internet Pro- tocol); ~ URL, pentru administrarea unei adrese URL (Uniform Resource Lo- calor), care indied o resursa Internet © java.util. jar = JarF ile, pentru administrarea unui figier JAR; = JarInputstrean, oferd facilititi de citire @ conginutului unui figier JAR: ~ JarOutputStream, ofert facilitii de scriere a unui figier JAR. © java-util.zip ~ 2ipPie, pentru administrarea unei athive ZIP; 313 = ZipInputStrean, oferi facilitiyi de citire a conjinutului unei athive ZIP: ~ Zipoutput Stream, ofert facilitii de scriere a unei arhive ZIP. Dintre pachetele prezentate, dou’ se detaseaza prin gradul foarte mare de uti- lizare, indiferent de natura aplicatici care se creaza Este vorba despre pachetele java. lang gi java.util, Asa cum am precizat, pachetul java. lang este importat implicit in orice aplicajie Java, drept urmare programatorul poate folosi clasele sale fri a fi nevoie si le importe explicit, C.2 Definirea de pachete de catre utilizator Sectiunea de fapi prezinta un exemplu simplu, dar detaliat, de creare si uti- lizare a propriilor pachete. Mediul de programare Java ofera spre uilizare pro- gramatorului, o mulfime de pachete Impreuni cu clasele aferente (de exemplu, java.util, java.math ete.). Dar pentru c& aceasti facilitate nu este in- {otdeauna suficient, mediul Java permite definirea propriilor pachete. Cu alte inte, programatorului Java fi este permis si igi organizeze clasele definite de pachete proprii. _Exemplul ales utilizeaza trei pachete: © com. te: © com. te: posesori © com.test Primul pachet, com. test .masini, vaingloba clase cu functionalitate apropi- aul, reprezentind diverse tipuri de masini. Asadar, vom avea clasele Dacia si Ferrari. Al doilea packet, com. test .posesori, va cuprinde clase ‘care descriu posesorii automobilelor din primul pachet. Printre aceste clase se numiri: Per soana, elasi asociatd unei persoane fizice si Firma, clasi aso- iat unei persoane juridice (firme), Programul principal, cu alte cuvinte clasa ExempluPachete, se va afla {in pachetul com. test $i va utiliza clase din celelalte dou pachete. Pentru ci definirea pachetelor are 0 influenti decisiva asupra locafiei unde trebuie s8 fie salvate fisierele sursi ale acestei aplicagii de test, considerim directorul de lueru c:\Javawork (pentru utilizatorii de Windows). Analog, utilizatoriialtorsis- teme de operare, vor putea implementa exemplul ales, considerind un director de lucru specific platoformei respective (/usr /Local/javawork este un ‘exemplu pentru platforma Linux). 314 Citeva detalii despre pachete sunt necesae in acest moment al consti aplicaii. In primul rind, numele pachetelrtrebuie si fie unice, entra a evita eventualle conflict care pot si apa la incircareaclaselor. Exstenfa a dou Pachete cu acelasi mime pune masina viral Java in situaja de a nu sti ce clases incaree, din primal pachet sau din al doilea. Consecinja imediata este faptul ef nu se pot crea pachete cu acelasi mume ea al pachetelorpredefinite de medial de programare Java (de exemplu java. ang, java.util ete) Sarcina de a gsi un ume unie penta flecare pachet poate fi usuratédack sunt respectate convene de programare Java (detalii im anexa B), Potrvit aces- tor conventi,putem crea pachete pornind de In domenial Internet dent, in cazal in care programatorulfirma define un astfel de nume (de exemplu pa chetul ro. fizmamea provine de Ia domeniol wirw, €irmamea.ro). Dac nu exist un domenia Internet, este necesari erearea unc combinafi de mime, care este putin probabil si se repee. Afirmafileanterioare sunt utile mai ales in cazal in cae apicafile create de domneavoastri sunt redistribute cite divert tilizatori, care ar putea flosi la randul lor alte pachete, del ali furnizor, Ex- emplal nostr ind unul de est, am ales ea nume de pachet com. test, nume care poate asgura unicitatea la niveluui caleulatonului pe care realizim apli- cafile Java de test, desi nu este personaliat cu informafi cu caracterunic (de exemplo, numele persoanei sa al firmei care a creat) Namele pachetului presupune ereareauneticrarhi de directoare conforma cul. incazul nos, cele tei pachot existent con. test, com. test .ma- sini si com. test .posesor’, presupin erearea urmatoaelordiretoar: com, com|test, com\test\naaini si com\test \posesorii conform icra 1 - test 1 1 - posesori Cele patru directoare sunt create in cadruldirectorului de lucrastbiltante- For (c:\javawork). In fccare dintre aceste directoae se afi igierele sursi ale claselor precizate anterior, in func de pachetal in care sunt definite: © Dacia. java, Ferrari. java se gisese in directonul c:\javawork\com\test\masini; 35 * Persoana. java si Firma. java in directorul c:\javawork\com\test \posesori; © ExempluPachete. java in directorul c:\javawork\com\test. Codul sursi al acestorfigiere este prezentat in continuare: Listing C.1: Codul sursi al casei Dacia 171 Fiateral com\teat \masini\Decie. Java uckage com. test -masiai ‘public class Daci st (fee Modelut_masinit (1310, 1300, Berlina, ete). 6/ > private String tips fee Creaza 0 Dacie cu modelul preeizat.+/ %— publte. Dacia(String. tipal) eo ce tip = tipuls Hoy “fee Retwrneaza tipul masinit+/ © public String returneazaTip() wf * return tips Listing C.2: Codul surst al clasei Ferrari 171 Fiateral com\tert\masini\ Pervert. java package com. test masini ‘public class Ferrari st {1 fee Modelut masinit (P50, ete). +f > private String tips ee Creaza un Ferrari cu modelul precizat.+/ & publle. Ferrai of FE tip = tipuls wood (String tipul) ‘fee Returneata tipul masiall +/ © public String returneazaTip() return tip: ") Listing C.3: Codul sursi al clasei Persoana \77Fisieral com\resi\posesori\Persoana.java package com. test. posesori “Import com. test masini +: Simport java-util-+: Spublic class Persoana a + fee Numele persoanei.+/ private Steiag mume b /ee Adresa persoanel.+/ fh private String adresay (ee Sir cm masinite Dacia detinute de persoana+/ ‘private Vector masini: (es Creaza 0 persoana cu numele si adresa specificate. +/ lie Persoana( String numele, String adresa_) e ume = numele » adresa = adresa_: » masini = new Vector sy » pablic. String returneazaNume » ny hes Adauga 0 masina Dacia celor aflate deja in poresic. 6/ a bite vold.adaugaDacia (Dacia. masina) » » masini .2dd(mesina ); a0 ew Returneaza masinile aflate in posesie.«/ public Vector returneazaMasin’ ( «ft oy 317 “) Listing C-4: Codul sursi al casei Firma <7 Bisieral com\ test\porerori\Firmajave package com. test -posesori Limport java. wtil +3 Fimport com. ‘est .masini +; public class Firma ut $ fee Mumete firmet./ private String mume: fee Mumar angafatt + private ine numarAngsjati; fae Sir cu masinile aflare in posesie.«/ "private Vector masini: mie > + Creaza o firma specificand numele si S # mumarul de angajatt public Firma(String numele, Int aumarulAngajatilor) uf a) > (2 Adauga un Ferrari celor aflate deja in posesie.+/ h public void adaugaFerrari( Ferrari masina) ze 2 masini .2dd(masina ): wy fee Returneaza mume.+/ > public String returmeazaNume() sf so 2 fee Returneaza masinile aflate in posesie. «/ public Vector returneazaMasini Q) « “oo “ Listing C.5: Utilizarea claselor din pachetele definite 77 Fisieral com\tost\ExemplaPachete Java package com-test ‘import com. test. masini .¢; Slmport com. test. posesori +; Cimport java-wtil-w: public el “ public static vold main(String [) args) .s ExempluPachete Persoana p= mew Persoana("Mircea loneseu", “*) Ee Dacia d= new Dacia ("1300"); " Mpersoana P detine masina d ” p-adaugeDacia(d) fF Vector ¥ = p.teturneazaMasini (): 5 Wafisarea tipurilor masinilor detinute de persoana > System-out-printin("Tipurile de masini detinute de a 's peretueneazaNume() +": "): for(int 180: 1 < vesize(): 144) 5 t » String tip = (Dacia) ¥, get(i ). returneazaTip 0) e System out-priat(tip +"): » 1 e System. out. printin("™)s » Firma firmaMea = new Firma( "Sun", 13000); » Ferrari (= new Pereari(°F50"): = “firma firmastea detine masine f s fiemeMea.adaugaFerrari(t): » v= firmaMes -returneazaMasini Qs System-out. printin(*Tipurile de masini detinute de * ” + firmaMea. returneazaNume (Q) + "2" a for(int f= 0; 1c vsize(): it) » t - String tip = ((Ferrari) v.get(i)).seturneazaTip (): ‘ System-out. print (tip +" "}: 20 “) up’ ce clasele au fost create, urmatoarea actiume const in setarea vari- 319 abilei de sistem CLASSPATH, prezentati in cadrul capitolului 4.4.3. Variabila CLASSPATH trebuie astfel setaté Incdt si conjind gi directorul de Iueru pen- tru aplicatia noastra de test. Pentru aceasta, utilizatorii de Windows execut’ uurmatoarea comand’ in cadrul unui prompt MS-DOS: set CLASSPATH=SCLASSPATHY; c:\javawork\ Pentru a verfica daci variabila CLASSPATH a fost actualizati, se lanseaz’ {in acelasi prompt MS-DOS comanda: echo $CLASSPATHE Comanda afigeaza informatii aseminatoare cu cele ce urmeazi -10:\jdk\1ib\tools. jar; e:\javawork\ \jdk\jre\lib\re. jary act printre locaileafgate se afd drectorul de lueru, atunci se poate trece ta pasul urmator. Urmatorul pas consti in compilarea claslor definite fn eadrul eelor tre pachete care compun exemplul. Pentru ea procesul de compilare S& fie mai ugor, se creaza un fier eu numele FisiereSursa, in directorul de Iuema (c:\javawork), avind urmatorul confinut com\test \ExempluPachet . java com\test \masini\Dacia. java com\test\masini\Ferrari. java com\test \posesori\Persoana. java com\test \posesori\Firma. java Apoi, in acelagi prompt MS-DOS in care s-a setat variabila CLASSPATH, saz figierele sursi ale aplicajiei test, utilizand din directorul de luenu comands: javac @fisieresursa Este foarte important ca toate comenzie i fe execatate tn acelagi prompt MS-DOS in cae sa sett variabila CLASSPATA, penta ch aceasti stare este valabili doar in cadralacelui prompt. in momentul tn care promptl respec Liv este inchs, se pieede modificarea realizata asupra variabilei CLASSPATH, revenindu-se la valoare iia. Pentru a face aceste modificii permanente, cle trebue sie efectoate in 320 « figienl autoexec.bat din directonul ridding, in cazulsistemelor Win- dows 95, 98, ME, urmate de repornirea calculatoral © sectiunea User Variables din Control Panel-> System-> Environment, in cazul sistemelor Windows NT, 2000, Deoarece numarul de figiere sursi este destul de mic pentru acest exemplu,folo- sirea comenzii anterioare este acceptabili. Dar, daci aplicatia pe care orealizati are un numar mare de clase, atunci este recomandat si utilizai utilitarul ant, prezentat in anexa A, pentru a compila figiercle aflate int-o ierarhie de ditec- Prin compilate, se creaza figierele .class respective, in cadrul acelorasi ditectoare cu cele sursi, Dacit se doreste separarea fisierelor sursi de cele -class, alunci comanda javac trebuie folositi cu opfiunea ~d, urmati de irectorul unde vor fi create fisierele . class. Trebuie menjionat c& acest now director nu este automat precizat in variabila CLASSPATH. De aceea, dacd op- afi pentra aceasta variant, va trebui si adiugayi personal directorul respectiv {in cadrul variabilei CLASSPATE. [Exemplul construt in aceasta secjiune se executd prin nularea in directorul de lueru a comenzii Java com.test .ExempluPachet Rezultatele afsate sunt: Tipurile de masini Dacia detinute de Mircea Tonescu: 1300 Tipurile de masini Ferrari detinute de Sun F50 Pentru a injelege in profunzime modul de Iueru eu pachete, si vedem eum ‘pisos Java pachetele si clase definite de programator. Mai nti, interpretorul Java (Java) cautk variabila de sistem CLASSPATH. Pornind de la ridicini, interpretoral preia, pe nd, fiecare nume de pachet si inlocuiestefiecare sim- bol". intalnit eu simbolul *\* sau "/® in functe de sistemul de operare pe care ruleaza, pentra a genera o cale relativis unde vor fi ciutate fsieele class. in cazul nostru, pachetal com.test .masins este transformat in com\test\masini. Apoi, aceasti cale relativi este concatenat la diferitele inteisi din variabila de sistem CLASSPATH, de exemplu c:\Javawork sau \jdk\Lib\tools. jarete. Fiecare dintreaceste concatenar mu reprezin- aliceva decatc8i absolute, unde interretorul cautafgierele «class (adic& 321 Dacia.class, Ferrari.class). Pentru exemplul nostry, interpretorul ‘pisos fisierle anteioare in directorul :\javawork\com\test\masini, fn acest moment se poste spune ci primele pachete realizate de dumnes- voastel sunt functionale. Exemplul ales a fost isi unul simpla pentra a putea {njelege pasii necesari de a erearea pachetelor si pina la rularea api le foloseste. Cu siguranfa cd de-a lungul timpului nu v8 vey. opi aici si acest, exemplu va fi urmat de altele, conjinnd ierarii de pachete din ce in ce mai complexe, C3 Arhive jar (Java ARel es) Athivele jax permit gruparea mai multor fisiereintr-un sigur fisierarhivat. {in mod obignuitfisierele conyinute de o arhiva jar sunt fisiere .class, impr uni cu diverse resurse care pot fi asociate cu o aplicajie (imagini, etc). Nu exist © interdicjie in ceea ce priveste tipul de fisiere confinute de o arhiv8 ar (aces- tea pot confine orice tip de figiere, ca de altfel orice alt format de arhivare, cum arfi zip, rar, ace, ar etc.) darin general sunt folositefisierele .class. Athivele jar oferi programatorilor anumite benefici: © compresie: athivele jax permit compresarea fisirelor pentru a fi stocate mai eficient; © simplificarea distribuirit aplicaiilor: aplicatia creat este distribuithcli- ceniilor sub forma unui singurfisier jax, care inglobeaza toate fisierele gi resursele necesare funcional aplicai © micsorarea timpului de transfer: pentea a fi descircate fisierele confinute de un fisier jar, este nevoie doar de o singuri conexiune HTTP si nu de cite o conexiune pentru flecare figier in parte; © portabilirate: ca parte a platformei Java, arhivele jax sunt portable, putnd fi utiizate Prd a fi modificate pe orice platforms cu suport Java; © extinderea functionalitayit plarformei Java: mecanismul de extindere o- ferit de platforma Java permite extinderea funcyionalitafii platformei prin adiugarea unor fisiere jar celor existente (printre arhivele existente in orice implementare Java se numéri gi rt. jar, ce confine API-ul Java predefinit, adic’ toatl ierarhia de clase pe care mediul Java o ofers spre utilizare programatorilor) Prin adugarea unor arhive noi, putefis& extin- ‘defi functionalitatea platformei Java. Un exemplu este extensia JavaMail, 322 LUAVA ARCHIVES) dezvoltaté de Sun, care reprezint& un API uilizat in programele Java pen- ‘ru transmiterea si recepfionarea de email-uri: «© versionarea pachetelor de clase: un fisiet jaz poate cuprinde date despre figierele pe care le confine, cum ar fi informayii despre cel care a creat pachetele gi despre versiunea pachetelor respective. 3.1 Utilizarea figierelor . jar Fisierele jar sunt athivate pe baza formatului zip, deci au aceleagi faci- Titi ca orice alt tip de arhiva (compresie fara pierderea dateloretc.). Pe lang aceste facilitaji de bazd, figierele jar au gi alte funcfionalitai mai avansate (rulatea unei aplicagii in format jar este una dintre ele), a ctor injelegere este condiionata de familiarizarea cu operatile fundamentale cu arhive jar: crearea unei arhive jar, vizualizarea, extragerea sau modificarea conjinutulut acest Operatile de bazi cu arhivele } ax se realizea7i folosind o aplicajie utiitars oferiti de platforma Java. Aceast& aplicaie utilitaré este in linie de comand’ sieste denumiti jar, putind f gist in directorul bin al distribugiei Java instalati pe calculatorul dumneavoastri, Pentru a testa prezenja utiitarului pe calculatorul dumneavoaste’, deschidejio fereastrit de comand (sau, altfel spus, tun prompt) si rulaji comanda jax. Implicit, vor fi afigate informaii ajutatoare despre aceasti comands, cum ar fi opfiunile de utlizare gi cAteva exemple. Tati, pentru inceput, un rezumat al celor mai frecvente operafii cu arhive jar’ ‘© crearea unei arhive jar (cu alte cuvinte, “impachetarea” figierelor gi a di- rectoarelor int-un singur fisier); © vizualizarea conjinutului unei athive jaz; + extragerea confinutului unei arhive © extragerea doar a anumitorfisiere conginute intr-o ar # modificarea conjinutului unei arhive Jar; « rularea unei aplicagii"impachetate” int-o arhiva Jar; C32. Crearea unui fisier . jar athiva jar este realizaté utilizind aplicatia utilitard jar in urmitoarea forma: 323 (6. ARKIVE YAR UAVA ARCHIVES) jar cf nume_fisier_jar nume_fisiere Optiunile si argumentele utiizate in aceasta comanda au urmatoarea sem- nificat © opfiunea c indict faptul cd este create o arhiv jar; «© opfiunea £ indict faptul cX arhiva este creat intr-un figier. Este important de rejinut faptul c& optiunile nu trebuie separate prin spatiu si c& ordinea de aparitie a lor nu conteazi, «© argumentul nume_fisier_jar reprezinté numelefisierului jaz rezuk- tat in urma arhivari, Poate fi folosit orice nume pentru a denumi un fisier ar. Prin conventic fgierele au extensia . jar, desi acest lucra nu este obligatoriu; ‘© argumentul nume_fisiere reprezintao listé de nume de figiere gi di- rectoare, separate prin spafiu, care vor fi introduse in arhiva. Numele acestora poate si confina si simbolul *, pentru a face referire Ia mai multe figiere in acelasi timp. In cazul ditectoarelor, conjinutul acestora ‘este addugat recurs Ia arhivas ‘Suplimentar, se pot folosis1 alte opfiuni, pe langd cele de bazi (cf): © opfiunea v afigeaz’t numele fiectirui fisier adaugat Ia arhiva, in timpul crear acesteia; «© opfiunea 0 indicd faptul cd arhiva nu va fl compresatt; * optiunea M indica faptul ca figieral manifest asociat arhivei nu este creat (detalii despre fisierele manifest sunt oferite mai tarzi in cadrul sectiunii ‘curente); + opfiunea m indica faptalc& pot fi preluate dintr-un figier manifest existent informatii necesare arhivei care va fi creat. in acest caz, comanda are uurmitoarea form’: jar cfm nume_fisier_manifest nume_fisier_jar nume_fisiere «# opfiunea ~C schimba directorul curent in timpul execu 324 3. ARV LUAVA ARCHIVES) {in continuare vom prezenta citeva exemple de creare a athivelor jaz, care uti- lizeaza figirele .cLass ale aplicajci de test cu masini si posesori, prezentata {n subeapitolul precedent. Aceste fisiere se aft conform calor stabilite in sub- ‘apitolul precedent, in directorul c: \avawork, cae are urmatoarea struct (pentru simplitate, sugerim mutarea celorlalte tipuri de fisere in alt director} ~ test ~ Dacia.class ~ Ferrari.class = posesori - Firma.class ~ Persoana.class ~ ExempluPachete.class fn prim exemplu de create a arhivelor jaz, in director ¢:\Javawork se lanseazi dintr-o fereasri de comands aplicajia ja att Jaz evf pachete. jar com {n fereastra de comanda se va vedea ceva asemanator cu textul urmitor: added manifest adding: com/(in = 0) (out= 0) (stored 0%) adding: com/test/(in = 0) (out= 0) (stored 08) adding: com/test/masini/(in = 0) (out= 0) (stored 0%) adding: com/test/masini/Dacia.class(in = 364) (out= 257) (deflated 29%) adding: com/test /masini/Ferrari.class(in = 368) 259) (deflated 298) com/test/posesori/(in = 0) (out= 0) (stored 0%) com/test /posesori/Persoana.class(in = 738) 432) (deflated 41%) adding: com/test/posesori/Firma.class(in = 730) (out= 439) (deflated 39%) adding: com/test/ExempluPachete.class(in = 1602) (out= 913) (deflated 43%) Deoarece com este un director, utilitarul jar a adaugat recursiv toate di rectoatele si fisierele confinute in el. Rezultatul execusiei acestei comenzi este 325 (6. ARKIVE YAR UAVA ARCHIVES) figieral pachete. jar, aflat in directonul curent, in care a fost lansatt co- ‘manda, Analizand textul afigat se poate observa ca fisierul proaspit creat este ‘comprimat. Exista si posibilitatea de a crea 0 arhivi pachete. jaz necomprimati, Pentru aceasta se lanseazi comanda: jar cv£0 pachetel. jar com ‘Aceastaafigeaz urmatorul text added manifest adding: com/(in = 0) (out= 0) (stored 0%) adding: com/test/(in = 0) (out= 0) (stored 08) adding: com/test/masini/(in = 0) (out= 0) (stored 08) adding: com/test/masini/Dacia.class(in = 364) {out= 364) (stored 0%) adding: com/test/masini/Ferrari.class(in = 368) 368) (stored 0%) com/test/poses com/test /poses 738) (stored 0%) adding: com/test/posesori/Firma.class(in = 730) (out= 730) (stored 08) adding: com/test/ExempluPachete.class(in = 1602) (out= 1602) (stored 0%) /(Gin = 0) (out= 0) (stored 0%) /Persoana.class(in = 738) ‘Am ales si dim o alti denumire arhivei din al doilea exemplu, pentru a putea compara dimensiunile celor dou fisiere jaz rezultate, Daci cel com- primat, denumit pachete. jar, are 3.792 de bytes, cel necomprimat, pachetel. jar,are 5.180 de bytes. uteji si cteajio athivi jaz folosind simbolul *, cain exemplul urmator: jar cvE pachete.jar * ‘Cu ajutorul acestui simbol sunt adaugate in athiva toate fisierele gi (recursiv) directoarele din directorul curent. Ultimul exemplu pe care il prezentim foloseste optiunea ~C, de schimbare ‘a directorului curent, Prin utilizarea acestei opfiuni, cde relative nu mai sunt plstrate in totalitate in cadrul fisirului jaz. Pentru a observa acest comporta- ‘ment al utilitarului jar, lansaji comanda: jar cvE pachete. jar -C com\test\ 326 LUAVA ARCHIVES) fn fereastra de comands se va afga: added manife: adding: masini/(in = 0) (out= 0) (stored 08) adding: masini/Dacia.class(in = 364) (out= 257) (deflated 29%) adding: masini/Ferrari.class(in (deflated 29%) adding: posesori/(in = 0) (out= 0) (stored 08) adding: posesori/Persoana.class(in = 738) (out= 432) (deflated 41%) adding: posesori/Firma.class(in = 730) (out= 439) (deflated 39%) adding: ExempluPachete.class(in = 1602) (ou (deflated 43%) 368) (out= 259) 913) Cu alte cuvinte, in timpul execufiei comenzii directonul curent a fost schim- bat in com\test, iar fgierele gi directoarele au fost adiugate ca si cum co- ‘manda ar fi fost executati in acel director. Usilitatea acestei opfiuni apare in ‘momentul in care se adaugi mai multe fisiete gi directoare lao athivi, deoarece atunci se poate schimba dinamic, dintr-o singura comand, director! curent de ‘execufie a utilitarului jar: C 3 Vigualizarea continutului unui figier . jar Conyinutul unui fisier jax poate fi vizualizat far a-l extrage propriu-zis din interiorul fisierului, Comanda standard utilizat pentru a realiza acest lucru este: jar té nume_fisier_jar COptiunile si argumentele utilizate de aceasti comand’ au urmitoarea sem- nifcayie: © optiunea t indica faptal cd se doreste vizualizarea confinutului unui figier jazi «© opfiunea £ indica faptul c& in linia de comands va fi specificat un nume 4e figier, al carui conyinut va fi afigat; © argumentul nume_t ccinui conyinut va fi afigat. x_jar reprezint& numele fisierului jar al 327 (6. ARKIVE YAR UAVA ARCHIVES) Suplimentar, se poate utiliza si opjiunea v pentru a objine informayii despre imensiunea fisicrelor ear intra in componenja athivei jax si datain momentul ultimei modifica la care au fost supuse. ‘Ca exemplu, lansaji in director c:\javaworrk urmatoarea comanda pen- tna a vedea care este conjinutul athivei pachete. jar, creat la sectiunea an- terioara(primul exemplu din suit) jar tf pachete. jar Rezultatul executiei acestei comenzi este urmatorul: META-INF/ META-INF /MANIFEST.ME com/ com/test/ con/test /masini/ com/test /masini/Dacia.class con/test /masini/Ferrari.class com/test /posesori/ com/test /posesori/Persoana.class com/test /posesori/Firma.class con/test /ExempluPachete.class Dupa cum se poate observa, este afigatfiecare director gi figier conjinut fisieral jar. Directorul META-INF gi fiers MANIFEST.ME, conjinut in acest director, reprezinté o componenti special a oricirui fier jar (paragre ful C35), flind plasate in fisier Ia momentul credrié acestuia. De asemenea, este util de refinut c& toate directoarele gi figirele listate au edi relative, de tipul celei de mai jos: com/test /masini /Dacia.class. 3.4 Extragerea continutului unui figier . jar Forma standard a comenzii cu ajutorul cireia se extrage conjinutul unui fisier jar este urmatoarea jar xf nume_fisier_jar [nume_fisiere_arhivate] COpfiunile si argumenteleutiizate au semnificayia: © opfiunea x indicd faptul c& este extras conginutul unui fsier jars «© opfiunea £ specifica faptul 8 fisierul jax al c&rui conginut va fi extras, este specificat in linie de comand, 328 3. ARV LUAVA ARCHIVES) ‘© argumentul nume_fisier_jar reprezinti numele figierului al c&rui ‘conginut va fi extras; ‘© argumentul nume_£isiere_arhivate esteun argument optional (mo- tiv pentru care apare inte caracterele { ]), reprezentind lista cu numele figierelor care vor fi extrase din figierul jaz, separate prin spayiu. Dact argumentul lipseste, atunci va fi extras intreg conginutul fisierului jar. ‘Cind extrage conjinutul unui figier jaz, utilitaral jax creazd copii ale igerelor si directoarelor care sunt extras, reproduedind structura de directoare pe care fisicrele au in eadrul athivei. Toate aceste copii sunt create in directorulcurent, fisirul jax rminind intact. ins, dacd exist fisiere cu acelagi nume in direc tonal curent, ele vor fi escrse. Ca exemplu, sh extragem conjinutularhivei pachete . jar. Pentru aceasta, ‘executajicomanda urmatoare din directorul ¢: \javawork, intro fereastri de ‘comands: jar xf pachete. jar Rezultatul execusici acestei comenzi sunt cele doud directoare conginute in arhiva, impreuna cu subdirectoarele si figierele pe care le congin. Aceste direc- toare sunt com, unde se aflé clasele aplicatiei de test, si META~INF, unde se giseste figieral MANIFEST.MP. Dupa cum se observa, toate figierele gi direc- toarele conjinute au fost extrase, iar figiensl pachete.. jar a rimas intact. Pentru aextrage doar anumitefigiere din arhiva jar, trebuie si Ie specifica ‘comanda: ‘ca argument. Ca exempla, execut jar xf pachete. jar com/test/posesori/Firma.class ‘Aceast comanda creaza ierathia de directoare com/test /posesori, cama in care nu exist in directorul curent, si apoi creaziio copie a fisierului Firma. class in directonl posesori. 3.5. Fisierul manifest al unei arhive jar Fisicrul manifest este un fisier special al unei arhive jaz, care congine in- formayii despre fisierele arhivate. Implicit, fgierul are numele MANIFEST .MF. Crearea unei arhive jar presupune, implicit, crearea unui fisier manifest, asociat cu respectiva arhiva. Fiecare arhiva Jar are un singur figier manifest, ‘care este automat creat in directorul META-LNF al arhivei. Numele figiera- lui manifest si al directorutui in care se afld acesta, nu pot fi modificate, deci {ntotdeauna fisierul manifest are locajia META~INF /MANIFEST.MP, 329, (C3 ARKIVE YAR UAVA ARCHIVES) Informayile conjinute intr-un figier manifest sunt de tipul "cheie: valoare”. De exempla, fisicrul manifest al ahivei pachete . jar are urmatorul conyinut: Manifest-Version: 1.0 Created-sy: 1.4.0 (Sun Microsystems Inc.) Fisiorul manifest conjine doui informajii despre athiva pachete. jar: versiunea fisierului manifest (specificati de cheia Manigest-Version) si ‘numele platformei Java care a creat figierul manifest respectiv (specificat de cheia Created-By) ‘Acesta este formatul standard al unui fisier manifest asociat unei arhive jar. Informayiile pe care le ofera diferd insi de Ia o arhiva la alta, in functie Ge scopul athivei, Cu alte cuvinte, pe Kinga acestea mai pot apare si altele, ‘care vor fi prezentate in continuare. Daca rolul pe care il are athiva jar este doar cel standard al unei arhive, cum ar fi compresia datelor, nu trebuie si va faceji probleme in legiturl cu fisierul manifest, pentru ci fisierul manifest nu are nici un rol in astfel de situafii. Dac’, insi, doriji ca arhiva jar si prezin- te functionalitgi speciale (avansate), atunci va trebui sii modificali conjinutul fisierului manifest, dar pentru aceasta mai intdi va trebui si cunoagteti ce tre- buie modificat in figierul manifest si, dupa aceea, cum trebuie si-1 modifica Pentru ca o aplicatie "impachetata" inten figier jax, si poati fi executati folosind acest format, este necesar’ specificarea "punctului de intrare” al apli- cafiei, adicd numele clasei in care se afl metoda main (), care este apelata in ‘azul in care aplicajia nu este arhivat Specificarea numelui cla Class. Pentru aplicajia noastra de test, informatia ara ast: Main-Class: com.test .ExempluPachete acd aplicafia dumneavoastra utilizeaza clase disponibile in alte arhive jar, atunci trebuie specificat acest lucru prin intermediul cheii Class~Path, Desi {in cazul aplicajiei noastre nu se folosese clase din alte arhive ar, iat un ex- ‘emplu de prezentare a acestei informajii Class-Path: test2.jar app/test3. jar Pentru a refine informayiireferitoare la versiunea pachetelor consinute intr- © athiva jar, se pot utiliza chei speciale. Iatd un exemplu, adaplat la datele cexistente in aplicafia noastr Name: com/test/masini 330 3. ARV LUAVA ARCHIVES) Specification-Title: "Clase de masini" Specification-Version: "1.0" Specification-Vendor: "X Software" Implementation-Title: "com.test.masini* Implementation-Version: "versiune de test 0.12" Implementation-Vendor: "X Software” Un astfel de set de informatii poate fi prezentat pentru fiecare pachet al aplicatici 3.6 Modificarea fisierului manifest al unei arhive jar ‘Modificarea fisierului manifest al unei arhive jax se realizeazi prin inter- ‘mediul opfiunii m pe care o oferd utilitarul jar. Opjiunea m permite adaigarea {in fisioral manifesta informaiilor dorte, in timpul operasiei de create a arhivei jar, Formatul standard al comenzii est: jar cfm nume_fisier_manifest nume_fisier_jar nume_fisiere ‘Dat fiind faptul c& prin aceasta comands se ereaza un fisier jar, opji cf si argumentele nume_fisier_jar si nume_fisiere au aceeasi sem- nificaje cu cea descrist la sectiunea de creare a unui figier jar. Prin urmare, singurele lucruri care mai trebuie precizate sunt: © optiunea m specific faptul ed se vor addiuga anumit ‘manifest creat automat la erearea unei arhive jar; «© argumentul nume_fisier_mani fest reprezintd numele fisierulu ‘care vor fi preluate informatile care vor fi adaugate in fisierul manifest. Ca exemplu, vom recrea athiva pachete.. jar, adiugind fisierului manifest citevainformajiicu caracter special, Astfel, in directorul curent, c:\javawork, se creazi un fisier cu numele info . txt, avnd urmitorul continu: Main-Class: com.test .ExempluPachete Name: com/test/masini Speci£ication-Title: "Clase de masini" Specification-Version: "1.0" Specification-Vendor: "CompaniaMea” 2331 (C3 ARKIVE YAR UAVA ARCHIVES) Implementation-Title: "com.test-masini* Implementation-Version: "versiune de test 0.12" Implementation-Vendor: "X Software" ‘Dupaice figierul este salvat, se executa comanda: Jar omf info.txt pachete. jar com Rezultatul execusiei acestei comenzi este arhiva pachete. jar. Pentru a vedea modificirile efectuate in figieru! manifest, extrageti acest fgier din athiva, Figienul ar trebui si arate astfe Manifest-Version: 1.0 Main-Class: com.test .ExempluPachete Created-sy: 1.4.0 (Sun Microsystems Inc.) Name: com/test /masini Specification-Title: "Clase de masini* Specification-Vendor: "X Software" Implementation-Vendor: "x Software" Specification-Version: "1.0" Implementation-Version: "versiune de test 0.12" Implementation-Title: "com.test.masini* Se observa ci noul fisier manifest este © combinatie intre fisierul standard ‘reat de utiliarul jar gifgieral info. txt. C37 Modificarea confinutului unui fisier . jax ‘Conyinutul unui fisier jax poate fi modifica folosind optiunea w a utilitaru- lui jar. Prin modificarea conjinutului unui figier jar se poate injelege atat ‘modificarea fisierului manifest asociat arhivei jax, cét si adiugarea unor noi figiore fn athiva jar. Forma standard a comen: este: jar uf nume_fisier_jar nume_fisiere COptiunile si argumenteleutilizate au urmatoarea semnificajie: © optiunea u semnificd faptul c& arhiva jar va fi modificata «© opfiunea £ specific’ faptul c& numele fisierului care va fi modificat este precizat in linie de comand; 332 es atv i uava avs ‘© argumentul nume_fisier_jar reprezint numele fisierului care este modificat (actualizat); «© argumentul nume_£isiere reprezinti o listi de fisiere ce vor fi adau- gate in arhiva, Daca se utilizeazit opjiumea m (aseminator cu sectiunea anterioars, de modifi- ‘care a figicrului manifest) atunci se poate modifica figieral manifest ala jar, concomitent cu adiugarea unor noi fisiere in arhiva Sar acd, de exemplu, se doreste adiugarea in arhiva pachete . jar a unui nou fisier new. gf, aflat in directorul curent,atunci se executé comanda: jar uf pachete.jar new.gif De asemenea, se poate modifica fisierul manifest al arhivei pachete. jar, prin execujia urmitoarei comenzi (figienul info. txt este cel definit la secti- uunea anterioara): jar umf info.txt pachete. jar C38 Rularea aplicafiilor Java "impachetate” intr-o arhiva jar Aplicai ‘comands ccare sunt arhivate in cadrul unui fisier jax pot fi rulate folosind java ~jar nume_fisier_jar Optiunea —jar specifica faptul ca aplicatia ce va fi rulata este continut: o athiva jar. Accastcomanda poate fi tilizaté doar dac i iieral manifest al arhivei jar este speciticat ‘punctl de intrare" al aplicajc,prin intermedi cheit Nain-Class. fn consecinga, penta a putea rua o apicaic coninutd intro arhiva jar, trebuie mai inti si modifica sina manifest pens a in- trode informatia cert fn exemplul nostra, odata ce valoarea chetiain~Class este specifica, se poate rua aplicayia tlizind comanda java jar pachete. jar Rezultatul executiei acestei comenzi este urmitorul: 333 (C3 ARKIVE YAR UAVA ARCHIVES) Tipurile de masini Dacia detinute de Mircea Ionescu: 1300 Tipurile de masini Ferrari detinute de Sun: 50 fn concluzie, setiunea destinai arivelor Jax prezinté modalitatea de « realiza opera de baz cu arhive jaz, precum si modalitatea de a rlaaplicatit conginute fa cadeulunei astfel de arive, infigind acestecaracterstit int ‘an mod simplu, la obiec, pln de exemple elocvente, pentru ca programatorul ‘5% poat surprinde faciityie putemice pe cae le ofera acestearhivespeciice platforme: Java. 334 D. Internationalizarea aplicatiilor. Colectii de resurse Pentru un birbatcurajs, flecare (ar reprezint o pare. Proverb grecese [Lumea in care trkim este mick si inde i devini din ce in ce mai mick pe zi ce rece. in mare misura, aesta este rezultatl implicit computerelo in vi- aa noastrd. Internal a devent tn ui ani principalul mjloc de comunicare {inte oameni, pentr cd oferi o modalitate foarte simp si rapid de comuni- care, Email sau navigara pe Internet nu mai repezintio necunoscata penta Imajortateadintre noi. Practc, putem spune cd trim intr-un imens sat, n care fiecare poate comunica simply gi rapid cu cela, Efectl globaliari se simte sin industria IT, unde programatoi tebuie si considere ca pasa de desfacere fnweaga planeta. Ei sunt nevoiti si dezvolteaplicait care pot ft uilizate din Los Angeles pin Ia Pari, fri ca acest lems sa implice un efort prea mare de programare. Cu alte cavine,sarcina lor este de «crea aplicai interationali- zate, Din acest punet de vedere, programatori Java pots fe lini, J2SDK oferi ointreaga ierathie de clase care permite adaplarea un aplicaji de lao limbafculturé a alta, cu un efor minim de implementare. in Java, rocesul este chiar mai simpla decd pare D.1_ Timpul, numerele si datele calendaristice Este foarte bine cunoscut faptul ci, datoriti diverselor popoare si culturi existente pe planeta noastri, nu existé un standard acceptat la scar planetarit pentru afigarea numerelor, a datelor calendaristice sau a timpului 335 J, TIMPUL, NUMERELE DATELE CALENDARISTICE ‘S& lum ca exemplu urmatoarea dat: 5/3/02, Pentru cei ce locuiese in Statele Unite, aceasta dati reprezinta data de 3 mai 2002, in timp ce pentru cei ce locuiese in Europa, aceasta reprezinti $ martie 2002. Dupai cum se poste ‘observa, modul in care componentele unei date (zi, lund, an) sunt combinate gi diferd de lao {ara la alta. In Statele Unite, formatul este in stilul luni/zvan, in timp ce in majoritatea gérilor din Europa formatul este zi/luni/an. Poate c& nu este o diferent mare, dar nu trebuie subestimata importaniaei pentru utilizatorii aplicatiior. Formatele de date sunt poate cele mai simple, Ce se poate spune despre formatele de reprezentare a timpului sau cele de reprezentare a sumelor de bani (formate monetare) sau a numerelor? Rispunsul va fi descoperit pe parcursul ‘acestei secfiuni a anexei Convenile de formate variazi de lao {ari la alta, uneori semnificativ. Ex- luafi in care aceste convenfii variaz’ chiar si in interiorul aceleasi fr teva exemple: ist Tati © Timpal Afisarea orelor, minutelor si secundelor pare si fie cea mai simpli din- tre sarcini, dar nu este aga. Diferenfe apar de exemplu la caractenul de separare a orelor de minute. Unele {ati folosese simbolul “ :" (21:13 PM), in timp ce altele (Italia etc.) folosese simbolul “.” (23.13). De asemenea, cele 24 de ore ale zilei pot fi reprezentate ca jumitii de zi de cite 12 ore (primul exemplu), sau cu ore cuprinse intre 0 gi 24 (al doilea cexemplu); © Datele calendaristice Exemplele anterioare au aritat eX pozifia zilei, a lunii si a anului into reprezentare de dati calendaristicl diferd de Ia 0 zoni la alta. Pe de alti parte, caracterul de separare diferd gi el de la “/”" in Statele Unite (de ‘exemplu, 5/3/02), la“. in Germania (de exemplu, 03.05.02). De asemenea, numele zilelor gi ale lunilor diferi de lao limba la alta; © Numerele Primul lucru care atrage atengia in cazul numerelor este separatorul zeci- mal. Statele Unite folosese simbolul “ .” (de exemplu, 3. 55), dar alte iri (Romania ete.) preferd simbolul “, "(de exemplu 3, 55). Pentru 1 imbunitii citirea numerelor mai mari, cifrele sunt grupate de obicei, objinandu-se mii, milioane, miliarde etc. in Statele Unite acest sim- bol este “, ” (de exemplu, 3, 403.45), iar in alte féri (Romania ete.) acest simbol este “.” (de exemplu, 3. 403, 45). Sumele de bani sunt il TIMPUL, NUMERELE §!DATELE CALENDARISTICE reprezentate de asemenea di nul $ folosit de Statele Unite gi alte {&ri (de exemplu, $3, 400.00), dar cexisti numeroase alte alternative. De la lansarea ei, Java a fost catalogatldrept solujia dezvoltsi de apliayiin- temajjonalzate, Dar pnd la apaifa JDK. 1, suportul penta internafionalizare a fost redus, incepand isi cu versiunea anterior aminttd, Suna inclus in dis- tribusia IDK pachetul java. text care confine clasele gi interfejele pentms ‘manevrarea textuui in formate locale specificediverselor cultur fnainte de a prezenta soluja Java pent tratarea stuafiloranterioare, est azul si prezentim noyiunea de localizare (engl. locale) si clasa Java asociat, Locale. © localizare poate desemna o regiune cultural, politic sau geograicl. De ‘exemplu, poate fi consideratkregiunea din eare provine un grup de persoane care vorbese aceeasi limb. Din acest motv, lima vorbitd de aceste persoane este important pentru o localizare. Nafionaltatea de asemenea, pent c8, de ‘exemplu, desi american si britaniti vorbese aceeagi Himba, ei au tous iden- ‘tii cultural dierte, in Java, ocalizarea este reprezentattprint- instant a clasei Locale din pachetul java.util, O instant aclasei Locale poate fi ereaté pentru orice limba i otic jar. Localizarea se ereazi pe baza numelorlimbii a fri pentra care se realizeaz8respectiva localizare. Ambele nume reprezink de fapt abre- vier’ fn conformitate cu standardele ISO. Codutileasociate limbilorreprezint& out litere mici ale alfabetului ca de exemplu "en" pentru englezi, in timp ce codurile asociate prior eprezinti dous ltere majuseule, ca de exemplu "US" entra Statele Unite acl doris vedet lista competi a acestorabrevier,vizitaji urmitoarele sitesi © nttp://www. ics.uci-edu/pub/ietf/nttp/related/ 180639. txt, pentru codurile asociate limbilor; © http://www. chemie. fu-berlin.de/diverse/doc/ 150_3166.. html, pentru codurile asociate firilor. Existd ins anumite valori predefinite pentru unele fri (Canada, Franja, Germa- nia, alia, Statele Unite ete.) sau pentru unele limb (engleza, franceza, italian’ etc.) identficabile in cadrul clasei Locale prin intermediul atributelor statice ale clasei (CANADA, FRANCE pentru firi sau, respectiv, ENGLISH, FRENCH, pentru limbi) 337 J, TIMPUL, NUMERELE DATELE CALENDARISTICE In general opera iterafionalizarea (formatarea une date calendarstice, de exempl),folosesc ca argument instanjaa clasei Locale. Dac acest lueru nu este specifica, atunc se foloseste localizarea implicit Exemplat 1 iM foloseste localizarea implicita in i/operatil de internationalizare SLocale loc = Locale. getDetault (Qs 1 Wafiseaza limba arociata localizarti curente {System -out. printin (loc. getDisplayLanguage ()) tHofiseara tara asociata localizaril curente + System. out. printla (loc. getDisplayCountry ()): Daci, de exemplu, localizarea implicit este reprezentati de ‘i Statele Unite, atunci seeventa de cod anterioari afigeaz ba englezi English United states Exemplul 2: Mereaza 0 tocalizare pentru Romania si limba romana “primal parametra este codul ISO pentru limba romana “al doilea porametra este codal 30 pentra namsle tacit Locate al = new Lacale ("ro Dy © localizare poate fi facut implicité pentru o instanjai a JVM-ului prin metoda set Default (), ca in exemplul urmitor, fn caren este variabila din exemplul precedent) (localizarea romana este setata ca flind Implicita Locale. setDefault(al): Mtocatizarea germana este setata ca fiind implicita Locale. setDerault (Locale GERMAN): Daci o localizare nu este ficut impliciti prin apelul metodei setDefault, tunel localizarea impliciti este reprezentati de limba in cate a fost instalatd disteibuyia J2SDK. ‘Timpul poate fi formatat utilizand clasa DateFormat. De asemenea, cu ajutonul acestei clase se pot formata si datele calendatistice sau se pot cons- ‘ui impul si datele calendaistice intro forma independenti de limb. Clasa ‘fer numeroase metode statice pentru objinerea timpului/datelor calendaris- tice, pe baza localizariiimplicite sau a uneia specificate explicit, $i pe baza unui 338 il TIMPUL, NUMERELE §!DATELE CALENDARISTICE rnumarde sir de formatare. Acestea incu opfunile FULL, LONG, MEDTUM, ssioRr. fn general, «© optiunea SHORT reprezinté datatimpul in forma: 10.12.02 sau 3:30 PM; © opfiunea MEDTUM formateaz’i data/timpul astfel: Dee 12, 2002; * opfiunea LONG formateaza datatimpul astfel: December 12, 2002 sau 3:30:55 PM; «© opfiunea FULL formateazi data/timpul astfel: Thursday, December 12, 2002 AD sau 3:30:55 PM PST. Pentru a putea formata timpul in localizarea curent’, este necesari objinerea tunel instanje, folosind metoda get TimeInstance () aclasei DateFormat. Formatarea propriu-zist se realizeaz’ cu metoda format (), ca in exemplul; \Hafisarea timputui forma scurta in locatizarea implicita :DateFormat tf = DateFormat. getTimetnstance( DateFormat SHORT); System out. printia (tf. format (new Date())): 2 //afisarea timpului Jorma scurta in localizare italiana str = DateFormat . getTimelustance (DateFormat -SHORT, F Locale ITALY): System. out. printla( tf. format (new Date())): Rezultatul executiei acestei seevenfe de cod arata astfel: 11:39 AM 11.39 Prima valoare afigati reprezinttimpul pentru localizarea implicit (engleza ‘azul nostru, iar cea de a doua reprezintd timpul in localizare italiani. Dife- renga de formatare dintre cele dour valori este cit se poate de cla. Pentru a formata data calendaristicd in localizarea curenti, se folosese me- todele getDaternstance() (pentru objinerea unei instange a clasei care permite administrarea datelor calendaristice) si format () (pentru formatarea propriu-zist), ale clasei DateFormat: \Hafisarea datel forma seurta in locatizarea implicita DateFormat tf = DateFormat. getDatelnstance (DateFormat SHORT); » System out. printin (tf, format (new Date ())); SWafisarea datei forma seurta in localizere italiana (tr = DateFormat . getDatelnstance (DateFormat -SHORT. 7 Locale ITALY): System. out. printa (ef, format (new Date ())): 339, J. TIMPUL, NUMERELE DATELE CALENDARISTICE 8 //ofisarea datei forma scurta in localizare_germana (15 DateFormat. getDatelnstance DateFormat -SHORT, E Locale GERMANY): ‘System out. printia (tf format new Date())) Secvenfa afiseazi urmatoarele valori pentru 19 ianuarie 2002, corespunci- toare localizariiimplicite (englezA, in cazul nostru), localizariiitaliene (a doua variant) si localizarit germane (a treia varianta) 1/19/02 19/01/02 19.01.02 Analog poate fi folositi metoda parse () , care, spre deosebire de metoda format (), care transforma o dati calendaristicd intr-un string, realizeaz.t o- perajia inversi, de creare a unei date calendaristice dintr-un string, ‘Numerele, procentele si sumele de bani se formateaza utiizand clasa Num berFormat, intrun mod asemanator cu cele prezentate anterior, ‘Agadar, pentru a formata un numar int-o localizare Ia alegere se utilizeazi metodele get Instance () si format () \/afisarea numerelor in localizarea implicita NumberFormat nf = NumberFormat. getInstance (): ) System out, printla (at, format (12500.5)): S/afisarea numerelor in localizare germane ‘nf = NumberFormat getInstance (Locale GERMANY) » System out. printla (af. format(12500.5)): Rezultatul este: 12,500.5 12.500,5 Prima valoare afigatd este pentru localizarea implicita (engleza in cazul nos- ‘ra, in timp ce cea de a doua este pentru localizarea german’. Formatarea procentelor se realizeaza prin metodele get Percent Instan- ce() si format () ‘/afisarea procentelor in localizarea britaniea NumberFormat nf = NumberFormat. getPercentInstance Locale UK); System. out, printin (al. format (0.3)); Rezultatul afisat in urma executiei acestei seevente este 308 340 D2. COLECTILE DE RESURSE ININTERNATIONALIZAREA APLICATILOR Formatarea monetari se realizeaz& prin getCurrencyInstance() si format (): \Wafizarea unei same de bani in localizarea implicita NumberFormat nf = NumberFormat getCurreneylnstance () 2 System out. printla (af. format (8399.99): S/fafisarea unei sume de bani in localizare italiana tn = NumberFormat. getCurrencylnstance (Locale ITALY); 1 System out. printla (tf. format (8599.99). Rezultatul poate considerat un pie surprinzator: $8,599.99 L, 8.600 ‘Surpriza o constituie faptul e& pentru lira italian’ nu se consider’ subdivi ziuni, sumele find rotunjite pentni a se objine valori intregi, acest lueru da- in comparatie cu celelalte ‘monede. Ca gin cazul datelorcalendaristice, se poate utiliza metoda parse () pentru a realiza operatiile inverse, de transformare a stringurilor in numere, robabil ei sunt programatori care considers timpului, a datelor calendaristice si a numerelor sunt doar detalii de afigare a rezultatelor si nu au implicaii foarte mari, Utilizator aplicapilor s-ar putea si nu fie de acord cu aceasti pozitie, in special din cauza faptului c& afigarea rezultatelor nu se face in conformitate eu asteptirile lor. De aceea, programa ‘ori trebuie si fie foarte atengi la acest dealiu pe care, poate, pani acum nu I-au tratat cu indeajuns de multa seriozitate, pentru a realiza.o afigare a datelor int-o form’ cat mai "prietenoast" torindu-se faptului ci moneda italiana este "slabi D.2_ Colectiile de resurse in internationalizarea apli- catiilor ‘Cand programatorii de la Sun au seris codul pentru cele dous clase, Date~ Format si NumberFormat, ei au fost cei care au decis ce localiza si suporte (englezi, francez’, german’ etc.) si au oferit astfel modalitatea de a realiza con- versiile de date pentru respectivele localizati. Deoarece vatiatile datelor calen- daristice gi ale numerelor nu sunt foarte mari ei au putut implementa clasele DateFormat si NumberFormat, in conformitate cu respectivele localizari, ditect in biblioteca de clase (API) pe care Java o ofr Din pacate, lucrurile nu au mai fost la fel de simple in cazul mesajelor de tip text. Ar fi fost imposibil pentru programatori de la Sun si anticipeze toate 34 D2. COLECTILE DE RESURSE IN INTERNATIONALIZAREA APLICATILOR imesajele de tip text folosite in aplicagi (existente sau viitoare) gi si ofere tradu- cerile necesare. Din acest motiv, au Hisat aceasta sarcind programatorilor Java ‘care realizeaza aplicajiiinternasionalizate. Aceasta inseamna ci programatorul Java este cel care decide ce localizari suport aplicatia, urmand ca to el si ofere traducerile mesajelor text pentru fiecare localizare suportata de aplicaja sa, Cu alte cuvinte, programatorul va crea 0 colectie de stringuri pentru © anumiti localizare si le va utiliza in diverse locuri pe parcursul aplicafici Pentru a realiza acest demers, implementatori limbajului Java au pus la dis- poziia programatorilorcolecile de resurse (engl. resource bundles), cunoscute altfel si sub numele de pachete de resurse. D.2.1 Un exemplu concret Colegfile de resurse inglobeazi toate informagile specifice unei anumite localiziti. Dupi cum am vizut in parageaful 7.5 (pagina 212), flecare resursi ‘este asociata cu o cheie, care riméne neschimbati pentru toate localizatile. Va- Toarea asociati acestei chei se schimbi insti pentru fiecare localizare tn parte, reprezentind de fapt traducerea in respectiva limb a informayiet deyinute de resursi ‘Si considerim urmatorul exemplu: dorim si realizim o aplicaje care afi- seaza in diverse limbi, nojiunile de calculator, hard-disk, monitor gi tastaturs. Deoarece aceste denumiri se vor schimba in cadrul colectiilor de resurse, fiind {nlocuite cu traducerile lo, trebuie sa le asociem cu niste chei care vor rimane neschimbate, Presupunem c& avem urmatoarele asocier cheie | valoare cale | calculator hdd | hard-disk mon | monitor tast | tastatura Asocierile de mai sus formeaza o colectie de resurse, cu patru perechi de tipul cheie-valoare. Pentru fiecare limba in care dorim si traducem aceste noji- uni, vom avea cate o colecjie de resurse in care cheile vor fi aceleasi cu cele an- terioare, iar valorile vor reprezenta traducerile potrivite pentru fiecare nofiune. ‘Vom considera c& avem traducerile nojiunilor anterioare in treilimbi: englez’, germani si francezi, Prin urmare, vom avea alte trei coleefii de resurse, cate luna pentra fiecare limba in eare facem traducerea: « pentru limba engleza 342 D2. COLECTILE DE RESURSE ININTERNATIONALIZAREA APLICATILOR cheie | Valoare cale | computer nda | hard disk mon | monitor tast | _—_‘keyboard © pentru limba german cheie | Valoare calc | Computer hde | Platte mon | Monitor tast | ‘Tastatur «© pentru limba francez cheie | Valoare calc | ordinateur nde | disque dur mon | moniteur tast | clavier Dupi cum se observ, faptul acese chei rimén neschimbate ne aj si aso- ciem corect fiecare nojine eu traducerea ei. Astfel, nofiunea calculator are in primol tabelasociatécheia ca ic, eae corespunde in urmatoarele tet tabele cuvintelor conputer, Computer, ordinates, cu alte cavinte am ‘objinut raduceren noiunil in care inte ele te imbi ‘Un set de colectt de resurse formeazi un grup. Grupul are un nume, ales sugestiv de programator. Anslog, fecae colecje de resurse din cade grup tre un nme, construit in mod unie: numielegrapului, urmat de numel timbi fn are sunt taduse resusele, de numele fi i de variant (variant reprezin- to subregiune aunt fir). Ukimele dout adiugari de nume sunt opfionale Numele limb gi celal pri sunt reprezentae prin abrevier de dou liter, in conformitae cu standardele 150. De exemplu, abrevierea penta Canada este CA", iar pent limba francezi este “fr. in majortatea cazuriloraceste nume sunt evidente Una aspect important legat de modu de construire a numelui une colestit de resurse este e8 fecare nume este separat de urmtorl prin simbolul "_ D2. COLECTILE DE RESURSE IN INTERNATIONALIZAREA APLICATILOR Important de rein estes faptul cd exist o colecie care are acelagi ume cu mvp din care face parte. Aceasta este denumitacolecia implicit ‘Desi modalitatea de denumite a coleilr din cadnl unui grup poate prea dificil a este de faptdestl de simp, Petra averifica aceasta firma, até ‘cum arataaceste denumir in exemplal nosru: am denumit grupul de coect Componente, ceca ce inscamna ci ntmele colectiet implicit este tot Com ponente. Considerim prima coletie prezentatt (cca in limba romana) ca ind implicit. Cea de a doua coletc, cea cu tradvceile in limba engleza se rnumeste, conform regli de demumire prezenaté anterior, Componente_en, Analog, cclelalte dou colecii se numese Componente_de si Componen- te_fr Tn continuare vom vedea cum implementewzi Java colecfile de resurse sub forma unorsubelase ale elaseiabstracte Resour ceBund!e: * ListResourceBundle * PropertyResourceBundle ‘Vom analiza fiecare dintre cele dou modalitiji mai detaliat in cele ce urmeazi. D.2.2 Implementarea colectiilor prin List ResourceBundle ListResourceBunde confine resursele in cadrul unor clase Java stan- dard, a ciror denumire este dati de numele fiecirei colecfii de resurse, aga cum ‘fost el stablit prin aplicarea regulii de denumire, Aceste clase trebuie si suprascrie metoda getContents () gi si ofere un sir care confine perechile de resurse (chee, valoare) de tipul Str ing. Pentru exemplul nostr, lucrurile stau astfel: primul rind avem colectia implicit, implementata in modul urmator figieral Componente. java) vip jae Componente extends ListResourceBundle 5) state Anal Object {}{] contents = | ‘ [eomp". “calculator” }, : harddisk" } : monitor” |, 5 fastaturs) 1 D2. COLECTILE DE RESURSE IN INTERNATIONALIZAREA APLICATILOR “] apoi, avem implementarea cole fisierul Componente_en. java): de resurse pentru limba engleza (in simport java util -w Spublic class Componente_en extends ListResourceBundle a f) atatie final Object [JI] contents 5 (eomp". "computer" } FI [ohdd® "hard disk" | ‘ moo" | "monitor", [tase "keyboard 5 1 5 publie Object J{] getContents () of implementarea colecti figierul Componente_de. java): je resurse pentru limba germana (in sTmport java util -w public class Componente_de extends ListResourceBundle a f) statie final Object [11] contents a (eomp". "Computer" } : [ohdd* ,"*Piatte® | 5 [mon | "Monitor", D (tase, "Tastatury 5 1 public Object (}{] getContents () » 4 {in final, implementarea colectiei de resurse pentru limba francez’ (in fisierul Componente_fr. java): 345 D2. COLECTILE DE RESURSE IN INTERNATIONALIZAREA APLICATILOR sTmport java wail public class Componente_fr extends ListResourceBundle a 5) static final Object 11) contents = | ji (eomp". “ordinateur” }, 5 [ohdd","*disque due”), : [mon *moniteur™}, : [tase “elavier") * K » By . " bie Object [IL] getContents C) (data clasleimplementat, ele pot futlzate cu succes, conform exemplult din paragrafulD.2.4. Pina atunc, iat céteva detali importante legate de implementarea colecj- itor de resurse prin aceasta metoda. In primul rind, clasele au exact acelagi ‘numecucel stabil Ia definireacolefilor: Componente, Conponente_en, Conponente_de, Componente_tr. In al doiea rind, informata de aso- ciere cheilor eu valrile corespuncatoare est cor Fiecare pereche cheie/valoare reprezinta un element al sirului contents. Din ‘cauza faptului eX datele sunt stocate in interiorul unor clase, apare un dezavan- ‘aj destul de important: clasele trebuie recompilate pentru orice modificare valorilor. Este motivul pentru care aceasté variant este mai pujin uilizati de programatori alternativi a acestei clase este clasa PropertyResourceBundle, ‘care refine resursele in figiere de proprietii D.2.3 Implementarea colectiilor prin PropertyResourceBundle Clasa PropertyResourceBundle foloseste un tip special de fisiere pentru a stoca informatile de mapare acheilor si a valorior. Aceste fisiere sunt ‘de fapt simple fsiere text, cu extensia .propert ies. Numele fiecdrui fisier de acest tip este dat tot de regula de denumire a colecfilor de resurse. Asadar, ‘n exemplul nostru sunt patra fisere de proprietigi cu urmatoarele denumi © Componente.properties © Componente_en.properties 346 D2. COLECTILE DE RESURSE IN INTERNATIONALIZAREA APLICATILOR © Componente_de.properties © Componente_fr.properties Formatul special al figierelor de proprietifi apare datorti faptului ci perechile ‘cheie/valoare sunt stocate pe cate o line separatd. Fiecare lini este formata din ccheie, urmati de semnul "=", iar final este adiugati valoarea asociati cheii Pentru exemplul nostru, cele patru fisiere .properties au urmatorul cconyinut: * fisierul Componente. properties: comp=calculator hd I-disk mon=monitor tast=tastatura « figierul Componente_en.properties: comp=computer hddehard disk monsmonitor tastekeyboard figierul Componente_de.properties: comp=Computer hdd=Platte tast=Tastatur « figierul Componente_fr .properties: comp-ordinateur hdd=disque dur mon=noniteur tasteclavier In acest momen, fiierele de proprietj sunt gata pens fu a7 D2. COLECTILE DE RESURSE IN INTERNATIONALIZAREA APLICATILOR D.2.4 Utilizarea colectiilor de resurse Indiferent c& agi optat pentru prima metoda de implementare a colectiilor de resurse (utilizénd clasa List ResourceBundle), sau pentru cea de a doua (prin intermediul clasei Proper tyResourceBund.e),utilizarea colectilor de resurse se realizeazi in acelasi mod. Agadar, dact doriji si treceti de la (© metoda la cealalta, nu trebuie s modificaji nimic in modul de utilizare a colectilor de resurse, Aceasta secjiune va arita cit de elegant se face traducerea nofiunilor alese i s System. out. printla ("EXCEPTION: * + : e.getMersage ())3 a Prezentat pe scurt, programul anterior seteaziilocalizarea implicit ca f- ind cea romani, iar apoi utilizeazi colectia de resurse atagati localizirit im- plicite (cu alte cuvinte, colectia de resurse impliciti, Componente), pentru a descoperi valorile atasate celor douiichei "comp" si "tast™, valori pe care le afigeazi, Rezultatul execufiei acestui program este calculator tastatura Analog se pot afisa valorile celorlalte chei 348. D2. COLECTILE DE RESURSE IN INTERNATIONALIZAREA APLICATILOR Pentru a vedea adaptabilitatea foarte bund a colecilor de resurse la modifi- carea limbilor folosite, realizayi in programul sursi anterior modificdrile nece- sare pentru ca programul si arate astfel: import java utiles dpublic elas ULIRB at public statle yold main(String) args) oo F try D t D Locale. setDefault(new Loeale("r0", “RO)) fA RerourceBundle rb = ResourceBundle . getBundle( FE “Componente”, Locale . ENGLISH); 5 String 5 = rh. getString ("comp"): eB System out. printin(s): 5 5 = 1b. gerString ("tase"): ™ System out. println(s): * } 5 eateh (Exception &) 5 t e System out. printin ("EXCEPTION: * + e fe. getMessage ()): » 1 sy “) ‘Modificarea consti in faptul cd sa schimbat localizarea, adicd limba curenta in care se fac afigirile de date este cea englez3. Dat fiind faptul c& localizarea ‘curenti este cea engleza, la rularea programului, Java va prelua valorile cheilor "comp" si "tast™ din colectia de resurse asociati limbii engleze, adic’ din colectia Componente_en. in urmacxecutici, vor fi afigate rezultatele: computer keyboard Analog se poate objine traducerea nofiunilor in celelalte dous limb pe care Je-am ales: germana si franceza. Pentru a realiza acest demers, rebuie doar si inlocuiji Locale .ENGLISH in programul anterior cu Locale. GERMAN $i ‘mai apoi cu Locale. FRENCH, ‘Un lucru important care trebuie amintt este legat de modul in care Java identifick pachetul de resurse pentru o anumiti localizare. Colectia este cata {in cadrul grupului din care face parte, conform pagilor algoritmului urmator, 349, D2. COLECTILE DE RESURSE IN INTERNATIONALIZAREA APLICATILOR clutarea incheindu-se in momentul in care este gisita colectia ciutata sau s-a ajuns la colectia implicit’, 1. bundleName_localeLanguage_localeCountry_localeVariant 2, bundleName_localeLanguage_localeCountry 3, bundleName_localeLanguage 4, bundleName_defaultLanguage_defaultCountry_defaultVariant 5, bundleName_defaultLanguage_defaulCountry 6, bundleName_defaultLanguage 7, bundleName bundletene reprezinti numele grupuli, iar LocaleLanguage, 1locale- Countzy si locallevariant se referi la limba, jaa si epiunea localizes specifcae,intimp ce default Language, defauleCountry sidefault- Variant se refer la localizarea implicit entra a injelege mai bine acest algortm de chutare a colectilor de resuse, vom arita cum se realizeazk clutarea in exemplul nos. Mai inti sh iden tiflcim numele din algoritm: bundLewame este in exemplal nostru Compo- nente, localebanguage este fe en (engleza), fie de (germans), fie £r (francera),in timp ee localeCountry si localeVari ant lipsese. Pe de altiparte, defau1tLanguage este ro (romina),in imp ce defaultCoun- try si defaultvariant lipsese de asemenea, ack, de exemplu, dorim si clutim colectia de resurse penta limba ger rani, trebuie si ciutim colefia cu numele Componente_de, eu alte euvinte bundiewane ia valoarea Componente, ir Loca leLanguage ia valoarea de. Pentra ci nu avem in acess situafie LocaleCountry sau Localeva rFiant, algoritmol va fi executat pin la pasul 3, cind se opreste pentm ci a sit colecia cu numele Conponente_de fnt-un mod aseminitor, dact dorim si ciutim colectia de resurse pen- tru limba franceza vorbti in Canada (new Locale ("é", "CA*)), fava va ciutacoletia cu numele Componente_f1_CA. Executind pasi algort- mului anterior, ne vom opri la pasa 3, penta ch nu exstéo colecie mumiti Componente_fx_Ca (si din acest motiv nu ne putem opr la pasul 2), dar existhuna numiti Componente_£, Agadar,in aceast sitajie vom aveatra- ducerte din limba francez’ standard, nu traducerile pent dalectl de iba francezi vorbitin Canada, 350 D3, INTERNATIONALIZAREA MESAJELOR DINAMICE Foryand un pic nota, dack dorim si ciutaim colectia de resurse pentru limba ind (Locale . ITALIAN), Java cauti colecjia de resurse cu numele Com- ponente_it, dar cum nu avem nici o component cu nume aseminator, ‘cAutarea se va incheia la pasul 7, la colectia implicit Componente, tradu- cerile fiind preluate din aceasta colecfi, Prin urmare, daci nu avem o colectie asociatd unei localizati specificate, traducerile vor fi oferte din colectia impli- cit Folosind tehnicile prezentate in primele dou’ sectiuni ale acestei anexe, se pot construi aplicai simple care afiseaza utilizatorului date in orice localizare. Datele pot fi valori ale timpului, date calendaristice, numere sau simple mesaje statice, cum ar fi cele prezentate anterior, Dacii dorim si folosim mesaje di namice (de genul: "x figiere au fost sterse"),lucrurile se modific’ destul de mult, Sectiunea urmétoare arati cum trebuie tratate mesajele de acest tip. D.3__ Internafionalizarea mesajelor dinamice Din perspectiva progeamatorului care rescrie aplicaiiints-o alt limba, cu- vintele sunt cea mai simpli parte ce trebuie implementata, De exemplu, cind se traduc cuvintele din englezi in german’, "Yes" devine "a", "No" devine "Nein" si asa mai departe. Chiar si frazele simple, de tipul "Do you want to save the modifications?", pot fi inlocuite in intregime cu tradu- cerile potrivite. Dacit traducerile s-ar rezuma doar la exemple simple, de tipul ccelor mentionate anterior, atunci nu ar fi probleme, Dar ce facem daca suntem nevoiti si traducem un mesaj de tipul: "You copied 2 files"? Spre de- cosebire de mesajele anterioare, acesta este un mesaj dinamic, confine informa ‘care se modificd in funcjie de alte opera. (© metoda de rezolvare ar putea fi impairea mesajului in mai multe parti, in aga fel incat partea dinamica a mesajului si fie desparité de cea staticd. Cu alte a trei pai: "You copied", "2" si "files". fn acest fel, partea dinamicd a mesajului ("2") este separata de cea static’. Apoi, ar urma ca cele dows parti static si fie preluate din colecfi de resurse, unde arf traduse separat, Practic, codul ar fi asemiinator cu: ResourceBundle rb = ResourceBundle. getBundle(* Strings") :String str = rb. getString("first") + aFiles + : th, getString ("second"): unde "first" si "second” ar fi cele cheile asociate celor dows pati statice ale mesajului, iar nFiles ar fi numarul de fisiere ce va fi copia, 351 D3, INTERNATIONALIZAREA MESA/ELOR DINAMICE Din picate, abordarea precedenti nu este universal valabili, deoarece este posibil ca in alte limbi ordinea cuvintelor si nu mai fie aceeasi, Desi noi am ‘considerat c& elementele care compun textul au o anumiti ordine, exist limbi {in care aceasta ordine nu poate fi respectati. De exemplu, in limba german’ verbele se pun la finalul propozitci. Din fericire, exista o solutie pentru aceasta problemé. Trebuie si credim un sablon corect din punct de vedere sintactic pentru fiecare localizare, iar apoi Ja executarea aplicajei sablonul este combinat cu partea dinamic& a mesajului (altfel spus, cu parametri), Abilitatea de a combina sablonul cu parametii este oferit in Java prin intermediul clasei NessageFormat. Primul pas care tebuie realizat este crearea cate unui sablon pentru fiecare localizare suportaté de aplicajie. Sablonul presupune inlocuirea pirtilor dina- mice ale mesajului, cu parametri, ca in exemplut: "you copied 2 files" --> "you copied (0) files" fn cazul most, singura pare dinamich a messjului este "2* gia fos in- Jocuité eu parametral "(0)". Dac ar fi existat mai multe pig dinamice in ‘adral mesajulu, parame ar fost (2), (2) ee CConsiderim gablonul anterior ca find asocitIoealiziitimplicie i cazal rosin, localizarea engleza). De asemenea, considerim si sablonul pent lo- calizarea romani: "Ati copiat (0} fisiere™ La executarea aplicafei, parametrul (0 } este inlocuit in cadrul sablonului, ‘cu numarul de figiere copiate, asa cum a fost el calculat in cadrul aplicatci Cele dou sabloane, cite unul pentru fiecare dintre cele dou localizasi, vor fi preluate din coleciii de resurse si folosite pentru a crea mesajele dinamice. Considerim ci numele grupului de coleetii este "Messages", iar cheia aso- ciata sablonului este "ms" Colecjia de resurse implicita este urmitoarea (Messages .propert ies): mag=You copied (0) files Pe de alti parte, colecjia de resurse pentna limba romani arati astfel(figieral Messages_ro.properties) msg=Ati copiat (0) fisiere Pentru localizarea imp! 352 1, seoventa de cod arata astfel: D3, INTERNATIONALIZAREA MESAJELOR DINAMICE 1 Resourceltundic rh = ResourceBundle. getBundle ("Messages"); )MessageFormat mf = new MessagePormat( rb. getString "msg" )): sObject{] args = (new Integer(2)) System out. pi tla (mf, format (args): La execuia codului va fi preluat din coletia implicit sablonul "You co- pied {0} files™. Prin apelului metodei format (), sablomul este com- binatcu vaorte flat in variabila args. Practc, prameti sablonulu sunt in- locuijicuvalorile de pe pore corespunzitoare dn siral args. In azul nos- tr, parameteu {0} esteinlocuiteu args {0} adicdcu elemental 2, obginindu~ se mesajulformatat "You copied 2 files". Pentru obfinereataduceri acest mesa in limba romana, modifica prima lini seovenei de cod anerioare, astfel inca s fede form ResourceBundie th = ResourceBundle getBundle( “Messages few Lovale ("ros RO!) Analog celorprezentate anterior, se va objine un messj deforma "Xt con plat 2 fisieret [Exempleleanterioare folosese cele mai simple forme de parametr in cadrul unui sablon, Java oferdposibiltatea de a realiza formatiri mult mai complexe. Un parametru este format de fapt din trei cdmpuri separate prin simbolul ‘© Primul cmp reprezinti un numir, care indic& pozitia din cadrul sirulut de obiecte, a obiectului cu care va fi fnlocuit parametrul la formatare. De ‘exemplu, parameteul 0 indict faptul e& va fi inlocuit eu elemental de pe Pozitia 0 din si, parametrul I cu elemental de pe poviia I ete. © Al doilea camp este optional gi se refer la tipul obiectelor formatate. Poate avea una din urmitoarele valori: time, date, number, choice: Al trilea cmp este de asemenea opjional si se refera la stilul de for- ‘matare a obiectelor. Daci formatul stabilit la punctul anterior este time sau date, atunci stilul poate avea valorile: short, medium, long, £u11 sau un stl de dati definit de utilizator. Daca formatuleste number, atunci stlul poate avea valorile: currency, percentage, integer, sau un stil de numar definit de u Tata citeva exemple de parametti {0} ~ formateaza elementul de pe pozitia 353 D3, INTERNATIONALIZAREA MESA/ELOR DINAMICE 0 din sir (0, time} - formateaza elementul de pe pozitia 0 din sir ca reprezentand timpul (0,date, short} - formateaza elementul de pe pozitia 0 din sir ca fiind o data calendaristica in format scurt (0, number, percent) - formateaza elementul de pe poz. 0 din sir ca fiind un procent Formatul choice este mai special sil vom descric in continuare, Opyiunea ‘choice (din lista de opiuni pentru edmpul al doilea al unui parametra) permite atagarea de mesaje unui anumit domeni de valori. Opjiunea este util pent ‘ci poate modifica mesajele in functie de anumite valori ale parametrilor. Dacis in exemplul nostru, valoarea parametrului ar fi fost I sau 0, mesajul ar fl aritat astfel: "You copied 1 files" "you copied 0 files" Prima propozitie nu este coreeti din punct de vedere gramatical (£iles ‘este la plural) si Java ne ajuti si evitdm o astfel de situate, prin folosirea opfi- unit choice. Opfiunea ne ofera posiblitatea de a modifica mesajul in functie de valoarea parametrului, astfelinc&t si avem urmatoarele mesaje: ‘© daci parametrul are valoarea 0, atunci mesajul este "You copied no files." daca parametral are valoarea 1, atunci mesajul este "You copied 1 file."; ‘© daci parametrul are valoarea > 1, atunci mesajul este "You copied N files. ",unde N este un numa ‘Sintaxa opfiunii choice este descrisi in continuare, Opjiunea este specificatd ‘aun set de alternative, separate prin simbolul "|". O alternativa consti dintr-o limitare numericd gi un mesaj. Alternativele sunt ordonate dupa limitarea nu- mericd. Limitarea reprezinta un numir double, care poate fi specificat in doua moduri: 354 D3, INTERNATIONALIZAREA MESAJELOR DINAMICE © N#,ce inseamna cX pentru toate valorile mai mari decatN, inclusiv, mesajul este valabil; © Nc, ce inseamni c& pentru toate valorile mai mari decit N, exclusiv, ‘mesajul este valabil Folosind opfiunea choice, gablonul mesajului nostru aratl astfel: "You copied (0, choice, 0#no files|1#1 file| 1<{0} files)" Desi pare destul de complicatd, la o privire mai atent’ se poate obseva ci utilizarea choice nu este chiar atit de dificil. $ablonul ne devalue cA for- ‘matarea se aplici parametrului 0, adica elementului de pe pozitia 0 din sirul de elemente, ca este o formatare de tipul alegere (engl. choice) cu treialter- native, separate prin doua simboluri "|". Prima alternativa indica faptul c mesajul "no files" va fi afigat pentru valori ale parametnului > 0 si < 1 (conform limitirii numerice a celei de a doua alternative), adic& pentru valoa- rea 0, Aseménator, alternativa a doua indica faptul ci mesajul "1 fie" este afigat pentru o valoare a parametruluiintre > 1 (limitarea numericda alternative! adoua) si < 1 (limitarea numericd a alterativei a treia), adic’ pentru valoarea parametrului. Alternativa a treia indici faptul pentru valori ale parametrului > 1, se afigeazii mesajul "NY £3 les", unde N este valoarea parametruli ‘Dupi cum se poate observa, limitirile numerice ale alternativelor sunt or- donate erescator (0,1, 1). Cu prezentarea formatiri mesajelor dinamice se incheie si ultima etapi care trebuie parcursii pentru a putea crea aplicafiiinternajionalizate la standarde pro- fesionale. Ajuns la acest nivel, programatorul Java trebuie si constientizeze faptul e¥ intemafionalizarea aplicajiilor nu mai reprezint& o irosire a timpului,

You might also like