|
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 | ||||||
|
||||||
h5d4dg 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.2 Instructiuni etichetate 5.3.2.3.1 Instructiunea if 5.3.2.4 Instructiuni de ciclare 5.3.2.4.1 Instructiunea while 5.3.2.5 Instructiuni de salt 5.3.2.5.1 Instructiunea break 5.3.2.6 Instructiuni de protectie 5.3.2.6.1 Instructiunea try 5.3.2.7 Instructiunea vida 5.3.1 Blocuri de instructiuni 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 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; 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 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. In cazul in care blocul mare este blocul de implementare al unei metode si metoda respectiva are parametri, acesti parametri sunt luati in considerare la fel ca niste declaratii de variabile care apar chiar la inceputul blocului. Acest lucru face ca numele parametrilor sa nu poata fi folosit in nici o declaratie de variabila locala din blocul de implementare sau subblocuri ale acestuia. In realitate, o variabila locala poate fi referita in interiorul unui bloc abia dupa declaratia ei. Cu alte cuvinte, domeniul de existenta al unei variabile locale incepe din punctul de declaratie si continua pana la terminarea blocului. Astfel, urmatoarea secventa de instructiuni: A x = 4; int x = 3; Acest mod de lucru cu variabilele face corecta urmatoarea secventa de instructiuni: A 5.3.2 Tipuri de instructiuni Locatie = valoare ; Specificarea locatiei se poate face in mai multe feluri. Cel mai simplu este sa specificam un nume de variabila locala. Alte alternative sunt acelea de a specifica un element dintr-un tablou de elemente sau o variabila care nu este declarata finala din interiorul unei clase sau numele unui parametru al unei metode. Valoarea care trebuie atribuita poate fi un literal sau rezultatul evaluarii unei expresii. Instructiunea de atribuire are ca rezultat chiar valoarea atribuita. Din aceasta cauza, la partea de valoare a unei operatii de atribuire putem avea chiar o alta operatie de atribuire ca in exemplul urmator: int x = 5; int y = 6; x = ( y = y / 2 ); x = y = y / 2; ( x = y ) = y / 2; In momentul atribuirii, daca valoarea din partea dreapta a operatiei nu este de acelasi tip cu locatia din partea stanga, compilatorul va incerca conversia valorii la tipul locatiei in modul pe care l-am discutat in paragraful referitor la conversii. Aceasta conversie trebuie sa fie posibila, altfel compilatorul va semnala o eroare. Pentru anumite conversii, eroarea s-ar putea sa nu poata fi depistata decat in timpul executiei. In aceste cazuri, compilatorul nu va semnala eroare dar va fi semnalata o eroare in timpul executiei si rularea programului va fi abandonata. 5.3.2.1.1 Atribuire cu operatie int x = 3; x = x * 4; vechea valoare a lui x este inmultita cu 4 si rezultatul inmultirii este memorat inapoi in locatia destinata lui x. Intr-o astfel de instructiune, calculul adresei locatiei lui x este efectuat de doua ori, o data pentru a lua vechea valoare si inca o data pentru a memora noua valoare. In realitate, acest calcul nu ar trebui executat de doua ori pentru ca locatia variabilei x nu se schimba in timpul instructiunii. Pentru a ajuta compilatorul la generarea unui cod eficient, care sa calculeze locatia lui x o singura data, in limbajul Java au fost introduse instructiuni mixte de calcul combinat cu atribuire. In cazul nostru, noua forma de scriere, mai eficienta, este: int x = 3; x *= 4; int x = 3, y = 5; double valoriai = new doublea10i; valoria( x + y ) / 2i += 3.5; calculul locatiei de unde se va lua o valoare la care se va aduna 3.5 si unde se va memora inapoi rezultatul acestei operatii este efectuat o singura data. In acest exemplu, calcului locatiei presupune executia expresiei: ( x + y ) / 2 si indexarea tabloului numit valori cu valoarea rezultata. Valoarea din partea dreapta poate fi o expresie arbitrar de complicata, ca in: valoriaxi += 7.0 * ( y * 5 ); *=, /=, %=, +=, -=, <<=, >>=, >>>=, &=, |=, ^= ^ 5.3.2.2 Instructiuni etichetate Eticheta cea mai simpla este un simplu identificator urmat de caracterul : si de instructiunea pe care dorim sa o etichetam: Eticheta: Instructiune ca in exemplul urmator: int a = 5; case Valoare: Instructiune default: Instructiune Exemple pentru folosirea acestor forme sunt date la definirea instructiunii. 5.3.2.3 Instructiuni conditionale 5.3.2.3.1 Instructiunea if Sintaxa acestei instructiuni este urmatoarea: if( Expresie ) Instructiune1 aelse Instructiune2i Dupa evaluarea expresiei booleene, daca valoarea rezultata este true, se executa instructiunea 1. Restul instructiunii este optional, cu alte cuvinte partea care incepe cu cuvantul rezervat else poate sa lipseasca. In cazul in care aceasta parte nu lipseste, daca rezultatul evaluarii expresiei este false se va executa instructiunea 2. Indiferent de instructiunea care a fost executata in interiorul unui if, dupa terminarea acesteia executia continua cu instructiunea de dupa instructiunea if, in afara de cazul in care instructiunile executate contin in interior o instructiune de salt. Sa mai observam ca este posibil ca intr-o instructiune if sa nu se execute nici o instructiune in afara de evaluarea expresiei in cazul in care expresia este falsa iar partea else din instructiunea if lipseste. Expresia booleana va fi intotdeauna evaluata. Iata un exemplu de instructiune if in care partea else lipseste: int x = 3; if( x == 3 ) x *= 7; si iata un exemplu in care sunt prezente ambele parti: int x = 5; if( x % 2 == 0 ) x = 100; else x = 1000; 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; int x = 3; int y = 5; if( y != 0 && x / y == 2 ) x = 4; 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 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; 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'; mesaj = "retur"; face ca in continuare sa fie executate si instructiunile de dupa cea etichetata cu default. 5.3.2.4 Instructiuni de ciclare 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; 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 ) 5.3.2.4.1 Instructiunea while 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; 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( true ) 5.3.2.4.2 Instructiunea do 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++; In instructiunea: int i = 1; do A tablouaii = 0; i += 2; 5.3.2.4.3 Instructiunea for 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; Iata un exemplu: int x = 0; for( int i = 3; i < 30; i += 10 ) x += i; 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; 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. 5.3.2.5.1 Instructiunea break De exemplu in secventa: int i = 1, j = 3; int tablouai = new inta10i; Instructiunea break cauzeaza iesirea fortata din bucla, chiar daca testul buclei i < 10 este in continuare valid. La terminarea tuturor instructiunilor de mai sus, i are valoarea 5. In exemplul urmator: int i, j = 3; int tablouai = new tabloua10i; do A tablouaii = 0; if( i++ >= j ) break; In cazul buclelor for, sa mai precizam faptul ca la o iesire fortata nu se mai executa instructiunea de reluare. Instructiunea break poate avea ca argument optional o eticheta, ca in: break Identificator; In acest caz, identificatorul trebuie sa fie eticheta unei instructiuni care sa includa instructiunea break. Prin faptul ca instructiunea include instructiunea break, intelegem ca instructiunea break apare in corpul instructiunii care o include sau in corpul unei instructiuni care se gaseste in interiorul corpului instructiunii care include instructiunea break. Controlul revine instructiunii de dupa instructiunea etichetata cu identificatorul specificat. De exemplu, in instructiunile: int i, j; asta: while( i < 3 ) A do A i = j + 1; if( i == 3 ) break asta; j = 10; De exemplu, in instructiunea: int i; S corpul buclei se executa de 10 ori, pentru ca a doua incrementare a lui i nu se executa niciodata. Executia incepe cu testul si apoi urmeaza cu prima incrementare. Dupa aceasta se executa instructiunea continue care duce la reluarea buclei, pornind de la test si urmand cu incrementarea si din nou instructiunea continue. In exemplul urmator: int i; do A i++; continue; i++; In sfarsit, in exemplul urmator: for( int i = 0; i < 10; i++ ) A continue; i++; 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 5.3.2.5.3 Instructiunea return 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 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 5.3.2.6.1 Instructiunea try 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 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 Sintaxa pentru o instructiune vida este urmatoarea: ; int x = 3; if( x == 5 ) ; else x = 5; |
||||||
|
||||||
|
||||||
Copyright© 2005 - 2024 | Trimite document | Harta site | Adauga in favorite |
|