Documente noi - cercetari, esee, comentariu, compunere, document
Documente categorii

Tipuri de instructiuni

Tipuri de instructiuni

1 Instructiuni de atribuire

O atribuire este o setare de valoare intr-o locatie de memorie. Forma generala a unei astfel de instructiuni este:

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 );

Valoarea finala a lui x va fi identica cu valoarea lui y si va fi egala cu 3. Parantezele de mai sus sunt puse doar pentru claritatea codului, pentru a intelege exact care este ordinea in care se executa atribuirile. In realitate, ele pot sa lipseasca pentru ca, in mod implicit, Java va executa intai atribuirea din dreapta. Deci, ultima linie se poate rescrie ca:

x = y = y / 2;

De altfel, gruparea inversa nici nu are sens:

( x = y ) = y / 2;

Aceasta instructiune va genera o eroare de compilare pentru ca, dupa executarea atribuirii din paranteze, rezultatul este valoarea 6 iar unei valori nu i se poate atribui o alta valoare.

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.

1.1 Atribuire cu operatie

Se intampla deseori ca valoarea care se atribuie unei locatii sa depinda de vechea valoare care era memorata in locatia respectiva. De exemplu, in instructiunea:

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;

Eficienta acestei exprimari este cu atat mai mare cu cat calculul locatiei este mai complicat. De exemplu, in secventa urmatoare:

int x = 3, y = 5;
double valori[] = new double[10];
valori[( x + y ) / 2] += 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:

valori[x] += 7.0 * ( y * 5 );

Iata toti operatorii care pot fi mixati cu o atribuire:

*=, /=, %=, +=, -=, <<=, >>=, >>>=,   &=, |=, ^= ^
1.2 Atribuiri implicite

Sa mai observam ca, in cazul folosirii operatorilor de incrementare si decrementare se face si o atribuire implicita pentru ca pe langa valoarea rezultata in urma operatiei, se modifica si valoarea memorata la locatia pe care se aplica operatorul. La fel ca si la operatiile mixte de atribuire, calculul locatiei asupra careia se aplica operatorul se efectueaza o singura data.

2 Instructiuni etichetate

Unele dintre instructiunile din interiorul unui bloc de instructiuni trebuie referite din alta parte a programului pentru a se putea directiona executia spre aceste instructiuni. Pentru referirea acestor instructiuni, este necesar ca ele sa aiba o eticheta asociata. O eticheta este deci un nume dat unei instructiuni din program prin care instructiunea respectiva poate fi referita din alte parti ale programului.

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;
Eticheta: a = 3;

Pentru instructiunea switch, descrisa mai jos, sunt definite doua moduri diferite de etichetare. Acestea au forma:

case Valoare: Instructiune

default: Instructiune

Exemple pentru folosirea acestor forme sunt date la definirea instructiunii.

3 Instructiuni conditionale

Instructiunile conditionale sunt instructiuni care selecteaza pentru executie o instructiune dintr-un set de instructiuni in functie de o anumita conditie.

3.1 Instructiunea if

Instructiunea if primeste o expresie a carei valoare este obligatoriu de tipul boolean. Evaluarea acestei expresii poate duce la doar doua valori: adevarat sau fals. In functie de valoarea rezultata din aceasta evaluare, se executa unul din doua seturi de instructiuni distincte, specificate de instructiunea if

Sintaxa acestei instructiuni este urmatoarea:

if( Expresie ) Instructiune1 [else Instructiune2]

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;

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 ) else

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.

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 )

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 )

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 )

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

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 tablou[] = new int[10];
int i = 0;
tablou[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.

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 tablou[] = new int[20];
while( i < 10 )
tablou[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:

while( true )

Intreruperea executiei unui ciclu infinit se poate face introducand in corpul ciclului o instructiune de salt.

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 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.

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 )

In fine, schema urmatoare reprezinta functionarea unei bucle for

Figura 5.6 Schema de functionare a buclei for.

5 Instructiuni de salt

Instructiunile de salt provoaca intreruperea fortata a unei bucle, a unui bloc de instructiuni sau iesirea dintr-o metoda. Instructiunile de salt sunt destul de periculoase pentru ca perturba curgerea uniforma a programului ceea ce poate duce la o citire si intelegere eronata a codului rezultat.

5.1 Instructiunea break

Instructiunea break produce intreruperea unei bucle sau a unui bloc switch. Controlul este dat instructiunii care urmeaza imediat dupa bucla intrerupta sau dupa blocul instructiunii switch

De exemplu in secventa:

int i = 1, j = 3;
int tablou[] = new int[10];
while( i < 10 )
i += 2;

sunt setate pe 0 elementele 1 si 2 ale tabloului. Dupa a doua iteratie i devine 3 si testul i == j are valoarea adevarat, producandu-se executia instructiunii break

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 tablou[] = new tablou[10];
do while( i < 10 );

sunt setate pe 0 elementele 0, 1, 2 si 3 din tablou. Daca va intrebati la ce mai foloseste testul buclei, atunci sa spunem ca este o masura suplimentara de siguranta. Daca cumva j intra cu o valoare gresita, testul ne asigura in continuare ca nu vom incerca sa setam un element care nu exista al tabloului. De fapt, pericolul exista inca, daca valoarea initiala a lui i este gresita, deci testul ar trebui mutat la inceput si bucla transformata intr-un while, ca cel de mai sus.

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 ) while( j++ < 3 );

j = 10;

instructiunea break termina bucla do si bucla while controlul fiind dat instructiunii de dupa while, si anume atribuirea:

j = 10;
5.2 Instructiunea continue

Instructiunea continue permite reluarea unei bucle fara a mai termina executia corpului acesteia. Reluarea se face ca si cum corpul buclei tocmai a fost terminat de executat. Bucla nu este parasita.

De exemplu, in instructiunea:

int i;
while( i < 10 )

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 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++ )

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++ )

instructiunea continue provoaca abandonarea buclei while si reluarea buclei for cu partea de reluare si apoi testul.

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.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.

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.

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 [catch( Argument ) Bloc2]*[finally Bloc3]

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

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.

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.

biologie

botanica






Upload!

Trimite cercetarea ta!
Trimite si tu un document!
NU trimiteti referate, proiecte sau alte forme de lucrari stiintifice, lucrari pentru examenele de evaluare pe parcursul anilor de studiu, precum si lucrari de finalizare a studiilor universitare de licenta, masterat si/sau de doctorat. Aceste documente nu vor fi publicate.