|
Politica de confidentialitate |
|
• domnisoara hus • legume • istoria unui galban • metanol • recapitulare • profitul • caract • comentariu liric • radiolocatia • praslea cel voinic si merele da aur | |
Instructiuni JAVA | ||||||
|
||||||
n1d6df 5.3.1 Blocuri de instructiuni 5.3.1.1 Declaratii de variabile locale 5.3.2 Tipuri de instructiuni 5.3.2.1 Instructiuni de atribuire 5.3.2.1.1 Atribuire cu operatie 5.3.2.1.2 Atribuiri implicite 5.3.2.2 Instructiuni etichetate 5.3.2.3 Instructiuni conditionale 5.3.2.3.1 Instructiunea if 5.3.2.3.2 Instructiunea switch 5.3.2.4 Instructiuni de ciclare 5.3.2.4.1 Instructiunea while 5.3.2.4.2 Instructiunea do 5.3.2.4.3 Instructiunea for 5.3.2.5 Instructiuni de salt 5.3.2.5.1 Instructiunea break 5.3.2.5.2 Instructiunea continue 5.3.2.5.3 Instructiunea return 5.3.2.5.4 Instructiunea throw 5.3.2.6 Instructiuni de protectie 5.3.2.6.1 Instructiunea try 5.3.2.6.2 Instructiunea synchronized 5.3.2.7 Instructiunea vida 5.3.1 Blocuri de instructiuni Un bloc de instructiuni este o secventa, eventual vida, de instructiuni si declaratii de variabile locale. Aceste instructiuni se executa in ordinea in care apar in interiorul blocului. Sintactic, blocurile de instructiuni sunt delimitate in sursa de caracterele A si S. In limbajul Java, regula generala este aceea ca oriunde putem pune o instructiune putem pune si un bloc de instructiuni, cu cateva exceptii pe care le vom sesiza la momentul potrivit, specificand in acest fel ca instructiunile din interiorul blocului trebuiesc privite in mod unitar si tratate ca o singura instructiune. 5.3.1.1 Declaratii de variabile locale O declaratie de variabila locala introduce o noua variabila care poate fi folosita doar in interiorul blocului in care a fost definita. Declaratia trebuie sa contina un nume si un tip. In plus, intr-o declaratie putem specifica o valoare initiala in cazul in care valoarea implicita a tipului variabilei, definita standard de limbajul Java, nu ne satisface. Numele variabilei este un identificator Java. Acest nume trebuie sa fie diferit de numele celorlalte variabile locale definite in blocul respectiv si de eventualii parametri ai metodei in interiorul careia este declarat blocul. De exemplu, este o eroare de compilare sa declaram cea de-a doua variabila x in blocul: A int x = 3; … A int x = 5; … S S Compilatorul va semnala faptul ca deja exista o variabila cu acest nume in interiorul metodei. Eroarea de compilare apare indiferent daca cele doua variabile sunt de acelasi tip sau nu. Nu acelasi lucru se intampla insa daca variabilele sunt declarate in doua blocuri de instructiuni complet disjuncte, care nu se includ unul pe celalalt. De exemplu, declaratiile urmatoare sunt perfect valide: A A int x = 3; … S … A int x = 5; … S S Practic, fiecare bloc de instructiuni defineste un domeniu de existenta a variabilelor locale declarate in interior. Daca un bloc are subblocuri declarate in interiorul lui, variabilele din aceste subblocuri trebuie sa fie distincte ca nume fata de variabilele din superbloc. Aceste domenii se pot reprezenta grafic ca in figura urmatoare: Figura 5.4 Reprezentarea grafica a domeniilor de existenta a variabilelor incluse
unul intr-altul. Figura 5.5 Reprezentarea grafica a domeniilor de existenta a variabilelor disjuncte. Instructiunea 1 nu poate lipsi niciodata. Daca totusi pe ramura de adevar a instructiunii conditionale nu dorim sa executam nimic, putem folosi o instructiune vida, dupa cum este aratat putin mai departe. In cazul in care dorim sa executam mai multe instructiuni pe una dintre ramurile instructiunii if, putem sa in locuim instructiunea 1 sau 2 sau pe amandoua cu blocuri de instructiuni, ca in exemplul urmator: int x = 5; if( x == 0 ) A x = 3; y = x * 5; S else A x = 5; y = x * 7; S Expresia booleana poate sa fie si o expresie compusa de forma: int x = 3; int y = 5; if( y != 0 && x / y == 2 ) x = 4; In acest caz, asa cum deja s-a specificat la descrierea operatorului &&, evaluarea expresiei nu este terminata in toate situatiile. In exemplul nostru, daca y este egal cu 0, evaluarea expresiei este oprita si rezultatul este fals. Aceasta comportare este corecta pentru ca, daca un termen al unei operatii logice de conjunctie este fals, atunci intreaga conjunctie este falsa. In plus, acest mod de executie ne permite sa evitam unele operatii cu rezultat incert, in cazul nostru o impartire prin 0. Pentru mai multe informatii relative la operatorii && si || cititi sectiunea destinata operatorilor. 5.3.2.3.2 Instructiunea switch Instructiunea switch ne permite saltul la o anumita instructiune etichetata in functie de valoarea unei expresii. Putem sa specificam cate o eticheta pentru fiecare valoare particulara a expresiei pe care dorim sa o diferentiem. In plus, putem specifica o eticheta la care sa se faca saltul implicit, daca expresia nu ia nici una dintre valorile particulare specificate. Sintaxa instructiunii este: switch( Expresie ) A acase ValoareParticulara: Instructiuni;i* adefault: InstructiuniImplicite;i S Executia unei instructiuni switch incepe intotdeauna prin evaluarea expresiei dintre parantezele rotunde. Aceasta expresie trebuie sa aiba tipul caracter, octet, intreg scurt sau intreg. Dupa evaluarea expresiei se trece la compararea valorii rezultate cu valorile particulare specificate in etichetele case din interiorul blocului de instructiuni. Daca una dintre valorile particulare este egala cu valoarea expresiei, se executa instructiunile incepand de la eticheta case corespunzatoare acelei valori in jos, pana la capatul blocului. Daca nici una dintre valorile particulare specificate nu este egala cu valoarea expresiei, se executa instructiunile care incep cu eticheta default, daca aceasta exista. Iata un exemplu de instructiune switch: int x = 4; … int y = 0; switch( x + 1 ) A case 3: x += 2; y++; case 5: x = 11; y++; default: x = 4; y += 3; S Daca valoarea lui x in timpul evaluarii expresiei este 2 atunci expresia va avea valoarea 3 si instructiunile vor fi executate una dupa alta incepand cu cea etichetata cu case 3. In ordine, x va deveni 4, y va deveni 1, x va deveni 11, y va deveni 2, x va deveni 4 si y va deveni 5. Daca valoarea lui x in timpul evaluarii expresiei este 4 atunci expresia va avea valoarea 5 si instructiunile vor fi executate pornind de la cea etichetata cu case 5. In ordine, x va deveni 11, y va deveni 1, x va deveni 4 si y va deveni 4. In fine, daca valoarea lui x in timpul evaluarii expresiei este diferita de 2 si 4, se vor executa instructiunile incepand cu cea etichetata cu default. In ordine, x va deveni 4 si y va deveni 3. Eticheta default poate lipsi, caz in care, daca nici una dintre valorile particulare nu este egala cu valoarea expresiei, nu se va executa nici o instructiune din bloc. In cele mai multe cazuri, aceasta comportare a instructiunii switch nu ne convine, din cauza faptului ca instructiunile de dupa cea etichetata cu case 5 se vor executa si daca valoarea este 3. La fel, instructiunile de dupa cea etichetata cu default se executa intotdeauna. Pentru a schimba aceasta comportare trebuie sa folosim una dintre instructiunile de salt care sa opreasca executia instructiunilor din bloc inainte de intalnirea unei noi instructiuni etichetate. Putem de exemplu folosi instructiunea de salt break care va opri executia instructiunilor din blocul switch. De exemplu: char c = '\t'; … String mesaj = "nimic"; switch( c ) A case '\t': mesaj = "tab"; break; case '\n': mesaj = "linie noua"; break; case '\r': mesaj = "retur"; default: mesaj = mesaj + " de"; mesaj = mesaj + " car"; S In acest caz, daca c este egal cu caracterul tab, la terminarea instructiunii switch, mesaj va avea valoarea "tab". In cazul in care c are valoarea CR, mesaj va deveni mai intai "retur" apoi "retur de" si apoi "retur de car". Lipsa lui break dupa instructiunea mesaj = "retur"; face ca in continuare sa fie executate si instructiunile de dupa cea etichetata cu default. 5.3.2.4 Instructiuni de ciclare Instructiunile de ciclare (sau ciclurile, sau buclele) sunt necesare atunci cand dorim sa executam de mai multe ori aceeasi instructiune sau acelasi bloc de instructiuni. Necesitatea acestui lucru este evidenta daca ne gandim ca programele trebuie sa poata reprezenta actiuni de forma: executa 10 intoarceri, executa 7 genoflexiuni, executa flotari pana ai obosit, etc. Desigur, sintaxa instructiunilor care se executa trebuie sa fie aceeasi, pentru ca ele vor fi in realitate scrise in Java o singura data. Totusi, instructiunile nu sunt neaparat aceleasi. De exemplu, daca executam in mod repetat instructiunea: int tablouai = new inta10i; int i = 0; tablouai++i = 0; in realitate se va memora valoarea 0 in locatii diferite pentru ca variabila care participa la calculul locatiei isi modifica la fiecare iteratie valoarea. La primul pas, se va face 0 primul element din tablou si in acelasi timp i va primi valoarea 1. La al doilea pas, se va face 0 al doilea element din tablou si i va primi valoarea 2, si asa mai departe. Lucrurile par si mai clare daca ne gandim ca instructiunea executata in mod repetat poate fi o instructiune if. In acest caz, In functie de expresia conditionala din if se poate executa o ramura sau alta a instructiunii. De exemplu instructiunea din bucla poate fi: int i = 0; if( i++ % 2 == 0 ) … else … In acest caz, i este cand par cand impar si se executa alternativ cele doua ramuri din if. Desigur, comportarea descrisa este valabila daca valoarea lui i nu este modificata in interiorul uneia dintre ramuri. 5.3.2.4.1 Instructiunea while Aceasta instructiune de buclare se foloseste atunci cand vrem sa executam o instructiune atata timp cat o anumita expresie conditionala ramane adevarata. Expresia conditionala se evalueaza si testeaza inainte de executia instructiunii, astfel ca, daca expresia era de la inceput falsa, instructiunea nu se mai executa niciodata. Sintaxa acestei instructiuni este: while( Test ) Corp Test este o expresie booleana iar Corp este o instructiune normala, eventual vida. Daca avem nevoie sa repetam mai multe instructiuni, putem inlocui corpul buclei cu un bloc de instructiuni. Iata si un exemplu: int i = 0; int tablouai = new inta20i; while( i < 10 ) tablouai++i = 1; Bucla while de mai sus se executa de 10 ori primele 10 elemente din tablou fiind initializate cu 1. In treacat fie spus, celelalte raman la valoarea 0 care este valoarea implicita pentru intregi. Dupa cei 10 pasi iterativi, i devine 10 si testul devine fals (10 < 10). In exemplul urmator, corpul nu se executa nici macar o data: int i = 3; while( i < 3 ) i++; Putem sa cream un ciclu infinit (care nu se termina niciodata) prin: ; Intreruperea executiei unui ciclu infinit se poate face introducand in corpul ciclului o instructiune de salt. 5.3.2.4.2 Instructiunea do Buclele do se folosesc atunci cand testul de terminare a buclei trebuie facut dupa executia corpului buclei. Sintaxa de descriere a instructiuni do este: do Corp while( Test ) ; Test este o expresie booleana iar Corp este o instructiune sau un bloc de instructiuni. Executia acestei instructiuni inseamna executia corpului in mod repetat atata timp cat expresia Test are valoarea adevarat. Testul se evalueaza dupa executia corpului, deci corpul se executa cel putin o data. De exemplu, in instructiunea: int i = 3; do i++; while( false ); valoarea finala a lui i este 4, pentru ca instructiunea i++ care formeaza corpul buclei se executa o data chiar daca testul este intotdeauna fals. In instructiunea: int i = 1; do A tablouaii = 0; i += 2; S while( i < 5 ); sunt setate pe 0 elementele 1 si 3 din tablou. Dupa a doua iteratie, i devine 5 si testul esueaza cauzand terminarea iteratiei. 5.3.2.4.3 Instructiunea for Instructiunea for se foloseste atunci cand putem identifica foarte clar o parte de initializare a buclei, testul de terminare a buclei, o parte de reluare a buclei si un corp pentru bucla. In acest caz, putem folosi sintaxa: for( Initializare Test ; Reluare ) Corp Corp si Initializare sunt instructiuni normale. Test este o expresie booleana iar Reluare este o instructiune careia ii lipseste caracterul ; final. Executia unei bucle for incepe cu executia instructiunii de initializare. Aceasta instructiune stabileste de obicei niste valori pentru variabilele care controleaza bucla. Putem chiar declara aici noi variabile. Aceste variabile exista doar in interiorul corpului buclei si in instructiunile de test si reluare ale buclei. In partea de initializare nu putem scrie decat o singura instructiune fie ea declaratie sau instructiune normala. In acest caz instructiunea nu se poate inlocui cu un bloc de instructiuni. Putem insa sa declaram doua variabile cu o sintaxa de forma: int i = 0, j = 1; Dupa executia partii de initializare se porneste bucla propriu-zisa. Aceasta consta din trei instructiuni diferite executate in mod repetat. Cele trei instructiuni sunt testul, corpul buclei si instructiunea de reluare. Testul trebuie sa fie o expresie booleana. Daca aceasta este evaluata la valoarea adevarat, bucla continua cu executia corpului, a instructiunii de reluare si din nou a testului. In clipa in care testul are valoarea fals, bucla este oprita fara sa mai fie executat corpul sau reluarea. Iata un exemplu: int x = 0; for( int i = 3; i < 30; i += 10 ) x += i; In aceasta bucla se executa mai intai crearea variabilei i si initializarea acesteia cu 3. Dupa aceea se testeaza variabila i daca are o valoare mai mica decat 30. Testul are rezultat adevarat (i este 0 < 30) si se trece la executia corpului unde x primeste valoarea 3 (0 + 3). In continuare se executa partea de reluare in care i este crescut cu 10, devenind 13. Se termina astfel primul pas al buclei si aceasta este reluata incepand cu testul care este in continuare adevarat (13 < 30). Se executa corpul, x devenind 16 (3 + 13), si reluarea, unde x devine 23 (13 + 10). Se reia bucla de la test care este in continuare adevarat (23 < 30). Se executa corpul unde x devine 39 (16 + 23) si reluarea unde i devine 33 (23 + 10). Se reia testul care in acest caz devine fals (33 < 30) si se paraseste bucla, continuandu-se executia cu prima instructiune de dupa bucla. Dupa iesirea din bucla, variabila i nu mai exista, deci nu se mai poate folosi si nu putem vorbi despre valoarea cu care iese din bucla, iar variabila x ramane cu valoarea 39. Pentru a putea declara variabila i in instructiunea de initializare a buclei for este necesar ca in blocurile superioare instructiunii for sa nu existe o alta variabila i, sa nu existe un parametru numit i si nici o eticheta cu acest nume. Daca dorim un corp care sa contina mai multe instructiuni, putem folosi un bloc. Nu putem face acelasi lucru in partea de initializare sau in partea de reluare. Oricare dintre partile buclei for in afara de initializare poate sa lipseasca. Daca aceste parti lipsesc, se considera ca ele sunt reprezentate de instructiunea vida. Daca nu dorim initializare trebuie totusi sa specificam implicit instructiunea vida. Putem de exemplu sa scriem o bucla infinita prin: int x; for( ;; ) x = 0; Putem specifica functionarea instructiunii for folosindu-ne de o instructiune while in felul urmator: Initializare while( Test ) A Corp Reluare ; S In fine, schema urmatoare reprezinta functionarea unei bucle for: Figura 5.6 Schema de functionare a buclei for. S while( i < 10 ); corpul se executa de 10 ori la fel ca si mai sus. Instructiunea continue duce la evitarea celei de-a doua incrementari, dar nu si la evitarea testului de sfarsit de bucla. In sfarsit, in exemplul urmator: for( int i = 0; i < 10; i++ ) A continue; i++; S corpul se executa tot de 10 ori, ceea ce inseamna ca reluarea buclei duce la executia instructiunii de reluare a buclei for si apoi a testului. Doar ceea ce este in interiorul corpului este evitat. Instructiunea continue poate avea, la fel ca si instructiunea break, un identificator optional care specifica eticheta buclei care trebuie continuata. Daca exista mai multe bucle imbricate una in cealalta buclele interioare celei referite de eticheta sunt abandonate. De exemplu, in secventa: asta: for( int i, j = 1; i < 10; i++ ) A while( j < 5 ) A j++; if( j % 2 == 0 ) continue asta; S S instructiunea continue provoaca abandonarea buclei while si reluarea buclei for cu partea de reluare si apoi testul. 5.3.2.5.3 Instructiunea return Instructiunea return provoaca parasirea corpului unei metode. In cazul in care return este urmata de o expresie, valoarea expresiei este folosita ca valoare de retur a metodei. Aceasta valoare poate fi eventual convertita catre tipul de valoare de retur declarat al metodei, daca acest lucru este posibil. Daca nu este posibil, va fi semnalata o eroare de compilare. Este o eroare de compilare specificarea unei valori de retur intr-o instructiune return din interiorul unei metode care este declarata void, cu alte cuvinte care nu intoarce nici o valoare. Instructiunea return fara valoare de retur poate fi folosita si pentru a parasi executia unui initializator static. Exemple de instructiuni return veti gasi in sectiunea care trateaza metodele unei clase de obiecte. 5.3.2.5.4 Instructiunea throw Instructiunea throw este folosita pentru a semnaliza o exceptie de executie. Aceasta instructiune trebuie sa aiba un argument si acesta trebuie sa fie un tip obiect, de obicei dintr-o subclasa a clasei de obiecte Exception. La executia instructiunii throw, fluxul normal de executie este parasit si se termina toate instructiunile in curs pana la prima instructiune try care specifica intr-o clauza catch un argument formal de acelasi tip cu obiectul aruncat sau o superclasa a acestuia. 5.3.2.6 Instructiuni de protectie Aceste instructiuni sunt necesare pentru tratarea erorilor si a exceptiilor precum si pentru sincronizarea unor secvente de cod care nu pot rula in paralel. 5.3.2.6.1 Instructiunea try Instructiunea try initiaza un context de tratare a exceptiilor. In orice punct ulterior initializarii acestui context si inainte de terminarea acestuia, o exceptie semnalata prin executia unei instructiuni throw va returna controlul la nivelul instructiunii try, abandonandu-se in totalitate restul instructiunilor din corpul acestuia. La semnalarea unei exceptii aceasta poate fi prinsa de o clauza catch si, in functie de tipul obiectului aruncat, se pot executa unele instructiuni care repun programul intr-o stare stabila. De obicei, o exceptie este generata atunci cand s-a produs o eroare majora si continuarea instructiunilor din contextul curent nu mai are sens. In finalul instructiunii, se poate specifica si un bloc de instructiuni care se executa imediat dupa blocul try si blocurile catch indiferent cum s-a terminat executia acestora. Pentru specificarea acestor instructiuni, trebuie folosita o clauza finally. Iata sintaxa unei instructiuni try: try Bloc1 acatch( Argument ) Bloc2i*afinally Bloc3i Daca, undeva in interiorul blocului 1 sau in metodele apelate din interiorul acestuia, pe oricate nivele, este apelata o instructiune throw, executia blocului si a metodelor in curs este abandonata si se revine in instructiunea try. In continuare, obiectul aruncat de throw este comparat cu argumentele specificate in clauzele catch. Daca unul dintre aceste argumente este instanta a aceleiasi clase sau a unei superclase a clasei obiectului aruncat, se executa blocul de instructiuni corespunzator clauzei catch respective. Daca nici una dintre clauzele catch nu se potriveste, obiectul este aruncat mai departe. Daca exceptia nu este nicaieri prinsa in program, acesta se termina cu o eroare de executie. Indiferent daca a aparut o exceptie sau nu, indiferent daca s-a executat blocul unei clauze catch sau nu, in finalul executiei instructiunii try se executa blocul specificat in clauza finally, daca aceasta exista. Clauza finally se executa chiar si daca in interiorul blocului 1 s-a executat o instructiune throw care a aruncat un obiect care nu poate fi prins de clauzele catch ale acestei instructiuni try. In astfel de situatii, executia instructiunii throw se opreste temporar, se executa blocul finally si apoi se arunca mai departe exceptia. Exemple de utilizare a instructiunii try gasiti in paragraful 9.2 5.3.2.6.2 Instructiunea synchronized Instructiunea synchronized introduce o secventa de instructiuni critica. O secventa critica de instructiuni trebuie executata in asa fel incat nici o alta parte a programului sa nu poata afecta obiectul cu care lucreaza secventa data. Secventele critice apar de obicei atunci cand mai multe parti ale programului incearca sa acceseze in acelasi timp aceleasi resurse. Ganditi-va, de exemplu, ce s-ar intampla daca mai multe parti ale programului ar incerca sa incrementeze in acelasi timp valoarea unei variabile. Una dintre ele ar citi vechea valoare a variabilei, sa spunem 5, ar incrementa-o la 6 si, cand sa o scrie inapoi, sa presupunem ca ar fi intrerupta de o alta parte a programului care ar incrementa-o la 6. La revenirea in prima parte, aceasta ar termina prima incrementare prin scrierea valorii 6 inapoi in variabila. Valoarea finala a variabilei ar fi 6 in loc sa fie 7 asa cum ne-am astepta daca cele doua incrementari s-ar face pe rand. Spunem ca cele doua regiuni in care se face incrementarea aceleiasi variabile sunt regiuni critice. Inainte ca una dintre ele sa se execute, ar trebui sa ne asiguram ca cealalta regiune critica nu ruleaza deja. Cea mai simpla cale de a face acest lucru este sa punem o conditie de blocare chiar pe variabila incrementata. Ori de cate ori o regiune critica va incerca sa lucreze, va verifica daca variabila noastra este libera sau nu. Instructiunea synchronized isi blocheaza obiectul pe care il primeste ca parametru si apoi executa secventa critica. La sfarsitul acesteia obiectul este deblocat inapoi. Daca instructiunea nu poate bloca imediat obiectul pentru ca acesta este blocat de o alta instructiune, asteapta pana cand obiectul este deblocat. Mai mult despre aceasta instructiune precum si exemple de utilizare veti gasi in partea a treia, capitolul 9. Pana atunci, iata sintaxa generala a acestei instructiuni: synchronized ( Expresie ) Instructiune Expresia trebuie sa aiba ca valoare o referinta catre un obiect sau un tablou care va servi drept dispozitiv de blocare. Instructiunea poate fi o instructiune simpla sau un bloc de instructiuni. 5.3.2.7 Instructiunea vida Instructiunea vida este o instructiune care nu executa nimic. Ea este folosita uneori, atunci cand este obligatoriu sa avem o instructiune, dar nu dorim sa executam nimic in acea instructiune. De exemplu, in cazul unei instructiuni if, este obligatoriu sa avem o instructiune pe ramura de adevar. Daca insa nu dorim sa executam nimic acolo, putem folosi un bloc vid sau o instructiune vida. Sintaxa pentru o instructiune vida este urmatoarea: ; Iata si un exemplu: int x = 3; if( x == 5 ) ; else x = 5; Caracterul ; care apare dupa conditia din if reprezinta o instructiune vida care specifica faptul ca, in cazul in care x are valoarea 5 nu trebuie sa se execute nimic. |
||||||
|
||||||
|
||||||
Copyright© 2005 - 2024 | Trimite document | Harta site | Adauga in favorite |
|