Documente Academic
Documente Profesional
Documente Cultură
Scurt istoric
Ce este Java?
Despre aceast carte
Convenii utilizate n aceast carte
Sugestii i reclamaii
Alte surse de informaii
Mulumiri
Scurt istoric
Limbajul Java mpreun cu mediul su de dezvoltare i execuie au
fost proiectate pentru a rezolva o parte dintre problemele actuale ale
programrii. Proiectul Java a pornit cu scopul declarat de a dezvolta
un software performant pentru aparatele electronice de larg
consum. Aceste echipamente se definesc ca: mici, portabile,
distribuite i lucrnd n timp real. De la aceste aparate, ne-am
obinuit s cerem fiabilitate i uurin n exploatare.
Limbajul luat iniial n considerare a fost C++. Din pcate, atunci
cnd s-a ncercat crearea unui mediu de execuie care s respecte
toate aceste condiii s-a observat c o serie de trsturi ale C++ sunt
incompatibile cu necesitile declarate. n principal, problema vine
din faptul c C++ este prea complicat, folosete mult prea multe
convenii i are nc prea multe elemente de definiie lsate la
latitudinea celor care scriu compilatoare pentru o platform sau
alta.
n aceste condiii, firma Sun a pornit proiectarea unui nou limbaj de
programare asemntor cu C++ dar mult mai flexibil, mai simplu i
mai portabil. Aa s-a nscut Java. Printele noului limbaj a fost
James Gostling care v este poate cunoscut ca autor al
editorului emacs i al sistemului de ferestre grafice NeWS. Proiectul
a nceput nc din 1990 dar Sun a fcut public specificaia noului
limbaj abia n 1995 la SunWorld n San Francisco.
Numele iniial al limbajului a fost Oak, numele unui copac care
crete n faa biroului lui James Gostling. Ulterior, s-a descoperit c
numele fusese deja folosit n trecut pentru un alt limbaj de
programare aa c a fost abandonat i nlocuit cu Java, spre deliciul
programatorilor care iubesc cafenelele i aromele exotice.
Ce este Java?
n primul rnd, Java ncearc s rmn un limbaj simplu de folosit
chiar i de ctre programatorii neprofesioniti, programatori care
doresc s se concentreze asupra aplicaiilor n principal i abia apoi
asupra tehnicilor de implementare a acestora. Aceast trstur
poate fi considerat ca o reacie direct la complexitatea
considerabil a limbajului C++.
Au fost ndeprtate din Java aspectele cele mai derutante din C++
precum suprancrcarea operatorilor i motenirea multipl. A fost
introdus un colector automat de gunoaie care s rezolve problema
dealocrii memoriei n mod uniform, fr intervenia
programatorului. Colectorul de gunoaie nu este o trstur nou,
dar implementarea acestuia n Java este fcut inteligent i eficient
folosind un fir separat de execuie, pentru c Java are ncorporate
faciliti de execuie pe mai multe fire de execuie. Astfel, colectarea
gunoaielor se face de obicei n timp ce un alt fir ateapt o operaie
de intrare-ieire sau pe un semafor.
Limbajul Java este independent de arhitectura calculatorului pe
care lucreaz i foarte portabil. n loc s genereze cod nativ pentru o
platform sau alta, compilatorul Java genereaz o secven de
instruciuni ale unei maini virtuale Java. Execuia aplicaiilor Java
este interpretat. Singura parte din mediul de execuie Java care
trebuie portat de pe o arhitectur pe alta este mediul de execuie
cuprinznd interpretorul i o parte din bibliotecile standard care
depind de sistem. n acest fel, aplicaii Java compilate pe o
arhitectur SPARC de exemplu, pot fi rulate fr recompilare pe un
sistem bazat pe procesoare Intel.
Una dintre principalele probleme ale limbajelor interpretate este
viteza de execuie, considerabil sczut fa de cea a limbajelor
compilate. Dac nu v mulumete viteza de execuie a unei astfel
de aplicaii, putei cere mediului de execuie Java s genereze
automat, plecnd de la codul mainii virtuale, codul specific mainii
pe care lucrai, obinndu-se astfel un executabil nativ care poate
rula la vitez maxim. De obicei ns, n Java se compileaz doar
acele pri ale programului mari consumatoare de timp, restul
rmnnd interpretate pentru a nu se pierde flexibilitatea. Mediul
de execuie nsui este scris n C respectnd standardele POSIX,
ceea ce l face extrem de portabil.
Sugestii i reclamaii
7
Capitolul I
Arhitectura calculatoarelor
1.1 Modelul Von Neumann de arhitectur a calculatoarelor
1.2 Organizarea memoriei interne
1.3 Reprezentarea informaiilor n memoria intern
1.4 Modelul funcional al calculatoarelor
10
11
13
14
15
Capitolul II
Limbaje de programare
2.1 Comunicaia om-main
2.2 Tipuri de numere reprezentabile n calculator
2.3 Valori de adevr
2.4 iruri de caractere
2.5 Tipuri primitive de valori ale unui limbaj de programare
2.6 Tablouri de elemente
2.7 Expresii de calcul
2.8 Variabile
2.9 Instruciuni
16
17
2.8 Variabile
Uneori, atunci cnd calculele sunt complexe, avem nevoie s
pstrm rezultate pariale ale acestor calcule n locaii temporare de
memorie. Alteori, chiar datele iniiale ale problemei trebuie
memorate pentru o folosire ulterioar. Aceste locaii de memorie
folosite ca depozit de valori le vom numi variabile. Variabilele pot
juca rol de operanzi n expresii.
Pentru a regsi valoarea memorat ntr-o anumit variabil, este
suficient s memorm poziia locaiei variabilei n memorie i tipul
de dat memorat la aceast locaie, numit i tipul variabilei.
Cunoaterea tipului variabilei este esenial la memorarea i
regsirea datelor. La locaia variabilei gsim ntotdeauna o
configuraie de cifre binare. Interpretarea acestor cifre binare se
poate face numai cunoscnd convenia de reprezentare care s-a
folosit la memorarea acelor cifre binare. Mai mult, tipul de variabil
ne i spune ci octei de memorie ocup locaia respectiv.
Pentru a putea referi variabilele n interiorul unui program, trebuie
s atribuim cte un nume pentru fiecare dintre acestea i s
rezervm locaiile de memorie destinate lor. Aceast rezervare a
locaiilor se poate face fie la pornirea programului fie pe parcurs.
24
2.9 Instruciuni
Operaiile care trebuiesc executate de un anumit program sunt
exprimate n limbajele de programare cu ajutorul unor instruciuni.
Spre deosebire de limbajele naturale, exist doar cteva tipuri
standard de instruciuni care pot fi combinate ntre ele pentru a
obine funcionalitatea programelor. Sintaxa de scriere a acestor
tipuri de instruciuni este foarte rigid. Motivul acestei rigiditi este
faptul c un compilator recunoate un anumit tip de instruciune
dup sintaxa ei i nu dup sensul pe care l are ca n cazul
limbajelor naturale.
Tipurile elementare de instruciuni nu s-au schimbat de-a lungul
timpului pentru c ele sunt coninute n nsui modelul de
funcionare al calculatoarelor Von Neumann.
n primul rnd, avem instruciuni de atribuire. Aceste instruciuni
presupun existena unei locaii de memorie creia dorim s-i
atribuim o anumit valoare. Atribuirea poate s par o operaie
foarte simpl dar realitatea este cu totul alta. n primul rnd,
25
execut instruciunea 1
altfel
execut instruciunea 2.
Cele dou ramuri de execuie sunt disjuncte n sensul c dac este
executat instruciunea de pe o ramur atunci cu siguran
instruciunea de pe cealalt ramur nu va fi executat. Dup
execuia uneia sau a celeilalte instruciuni ramurile se reunific i
execuia i continu drumul cu instruciunea care urmeaz dup
instruciunea condiional.
altfel
execut instruciunea implicit.
Un al treilea tip de instruciuni elementare sunt instruciunile de
ciclaresau repetitive sau buclele. Acestea specific faptul c o
instruciune trebuie executat n mod repetat. Controlul ciclurilor
de instruciuni se poate face pe diverse criterii. De exemplu se poate
executa o instruciune de un numr fix de ori sau se poate executa
instruciunea pn cnd o condiie devine adevrat sau fals.
Condiia de terminare a buclei poate fi testat la nceputul buclei
sau la sfritul acesteia. Dac condiia este testat de fiecare dat
nainte de execuia instruciunii, funcionarea ciclului se poate
descrie prin:
Atta timp ct Condiia este adevrat
execut Instruciunea
Acest tip de instruciuni de ciclare poat numele de cicluri while,
cuvntulwhile nsemnnd n limba englez "atta timp ct . n
cazul ciclurilor while, exist posibilitatea ca instruciunea din
interiorul ciclului s nu se execute niciodat, dac condiia este de
la nceput fals.
Execut Instruciunea
atta timp ct Condiia este adevrat.
Acest tip de instruciuni de ciclare poart numele de cicluri do-while,
cuvntul do nsemnnd n limba englez "execut . n cazul
ciclurilor do-while instruciunea din interiorul ciclului este garantat
c se execut cel puin o dat, chiar dac valoare condiiei de
terminare a buclei este de la nceput fals.
30
Capitolul III
Reprezentarea informaiilor cu obiecte
3.1 Obiecte
3.2 ncapsularea informaiilor n interiorul obiectelor
3.3 Clase de obiecte
3.4 Derivarea claselor de obiecte
3.5 Interfee spre obiecte
3.1 Obiecte
Informaiile pe care le reprezentm n memoria calculatorului sunt
rareori att de simple precum culorile sau literele. n general, dorim
s reprezentm informaii complexe, care s descrie obiectele fizice
care ne nconjoar sau noiunile cu care operm zilnic, n interiorul
crora culoarea sau o secven de litere reprezint doar o mic
parte. Aceste obiecte fizice sau noiuni din lumea real trebuiesc
reprezentate n memoria calculatorului n aa fel nct informaiile
specifice lor s fie pstrate la un loc i s se poat prelucra ca un
tot unitar. S nu uitm ns c, la nivelul cel mai de jos, informaia
ataat acestor obiecte continu s fie tratat de ctre compilator ca
un ir de numere naturale, singurele informaii reprezentabile direct
n memoria calculatoarelor actuale.
Pentru a reprezenta n memoria intern obiecte fizice sau noiuni,
este nevoie s izolm ntregul set de proprieti specifice acestora i
s l reprezentm prin numere. Aceste numere vor ocupa n
memorie o zon compact pe care, printr-un abuz de limbaj, o vom
numi, ntr-o prim aproximare, obiect. Va trebui ns s avei
ntotdeauna o imagine clar a deosebirii fundamentale dintre un
obiect fizic sau o noiune i reprezentarea acestora n memoria
calculatorului.
De exemplu, n memoria calculatorului este foarte simplu s crem
un nou obiect, identic cu altul deja existent, prin simpla duplicare a
zonei de memorie folosite de obiectul pe care dorim s-l dedublm.
n realitate ns, este mult mai greu s obinem o copie identic a
unui obiect fizic, fie el o simpl foaie de hrtie sau o bancnot de
10000 de lei.
S revenim ns la numerele naturale. Din moment ce ele sunt
singurele entiti reprezentabile n memoria calculatorului, este
firesc ca acesta s fie echipat cu un set bogat de operaii predefinite
31
Figura 3.1 Modelul de reprezentare al unui obiect n memorie. Stratul exterior reprezint doar
operaiile care ofer calea de a interaciona cu proprietile obiectului i nu are corespondent
direct n zona de memorie ocupat de obiect.
37
Figura 3.2 O ierarhie de clase de obiecte n care clasele sunt reprezentate n cmpuri eliptice
iar instanele acestora n cmpuri dreptunghiulare. Clasele abstracte de obiecte au elipsa
dublat.
40
Capitolul IV
Structura lexical Java
4.1 Setul de caractere
4.2 Uniti lexicale
4.2.1 Cuvinte cheie
4.2.2 Identificatori
4.2.3 Literali
4.2.3.1
4.2.3.2
4.2.3.3
4.2.3.4
4.2.3.5
Literali ntregi
Literali flotani
Literali booleeni
Literali caracter
Literali ir de caractere
4.2.4 Separatori
4.2.5 Operatori
4.3 Comentarii
42
Cuvinte cheie
Identificatori
Literali
Separatori
Operatori
for
future
generic
goto
if
implements
import
inner
instanceof
public
rest
return
short
static
super
switch
synchronized
this
43
const
continue
default
do
double
else
extends
final
finally
float
intinterface
long
native
new
null
operator
outer
package
private
protected
throw
throws
transient
try
var
void
volatile
while
byvalue
Dintre acestea, cele ngroate sunt efectiv folosite, iar restul sunt
rezervate pentru viitoare extensii ale limbajului.
4.2.2 Identificatori
Identificatorii Java sunt secvene nelimitate de litere i cifre Unicode,
ncepnd cu o liter. Identificatorii nu au voie s fie identici cu
cuvintele rezervate.
Cifrele Unicode sunt definite n urmtoarele intervale:
Reprezentare Unicode Caracter ASCII
\u0030-\u0039
0-9
Explicaie
cifre ISO-LATIN-1
\u0660-\u0669
cifre Arabic-Indic
\u06f0-\u06f9
\u0966-\u096f
cifre Devanagari
\u09e6-\u09ef
cifre Bengali
\u0a66-\ u0a6f
cifre Gurmukhi
\u0ae6-\u0aef
cifre Gujarati
\u0b66-\u0b6f
cifre Oriya
\u0be7-\u0bef
cifre Tamil
\u0c66-\u0c6f
cifre Telugu
\u0ce6-\u0cef
cifre Kannada
\u0d66-\u0d6f
cifre Malayalam
\u0e50-\u0e59
cifre Thai
\u0ed0-\u0ed9
cifre Lao
\u1040-\u1049
cifre Tibetan
Tabelul 4.1 Cifrele Unicode.
44
Caracter
ASCII
Explicaie
\u0024
\u0041-\u005a
A-Z
\u005f
\u0061-\u007a
a-z
\u00c0-\u00d6
\u00d8-\u00f6
\u00f8-\u00ff
\u0100-\u1fff
\u3040-\u318f
\u3300-\u337f
\u3400-\u3d2d
\u4e00-\u9fff
\uf900-\ufaff
compatibilitate Han
Tabelul 4.2 Literele Unicode.
4.2.3 Literali
Un literal este modalitatea de baz de exprimare n fiierul surs a
valorilor pe care le pot lua tipurile primitive i tipul ir de caractere.
Cu ajutorul literalilor putem introduce valori constante n variabilele
de tip primitiv sau n variabilele de tip ir de caractere.
n limbajul Java exist urmtoarele tipuri de literali:
literali
literali
literali
literali
literali
ntregi
flotani
booleeni
caracter
ir de caractere
45
Caracterul reprezentat
'\b'
'\t'
'\n'
'\f'
'\r'
'\"'
'\''
'\\'
49
greit!
Exemple de separare:
a[i]sin(56)
4.3 Comentarii
Un comentariu este o secven de caractere existent n fiierul
surs dar care servete doar pentru explicarea sau documentarea
sursei i nu afecteaz n nici un fel semantica programelor.
n Java exist trei feluri de comentarii:
51
Capitolul V
5.1 Variabile
5.1.1 Declaraii de variabile
5.1.1.1 Tipul unei variabile
5.1.1.2 Numele variabilelor
5.1.1.3 Iniializarea variabilelor
5.1.2 Tipuri primitive
5.1.2.1 Tipul boolean
5.1.2.2 Tipul caracter
5.1.2.3 Tipuri ntregi
5.1.2.3.1 Tipul octet
5.1.2.3.2 Tipul ntreg scurt
5.1.2.3.3 Tipul ntreg
5.1.2.3.4 Tipul ntreg lung
5.1.2.4 Tipuri flotante
5.1.2.4.1 Tipul flotant
5.1.2.4.2 Tipul flotant dublu
5.1.2.4.3 Reali speciali definii de IEEE
5.1.3 Tipuri referin
5.1.3.1 Tipul referin ctre o clas
5.1.3.2 Tipul referin ctre o interfa
5.1.3.3 Tipul referin ctre un tablou
5.1.4 Clasa de memorare
5.1.4.1 Variabile locale
5.1.4.2 Variabile statice
5.1.4.3 Variabile dinamice
5.1.5 Tablouri de variabile
5.1.5.1 Declaraia variabilelor de tip tablou
5.1.5.2 Iniializarea tablourilor.
5.1.5.3 Lungimea tablourilor
52
Tipul ntreg scurt este similar cu tipul octet dar valorile sunt
reprezentate pe doi octei, adic 16 bii. La fel ca i la tipul octet,
valorile
sunt ntotdeauna cu semn i se folosete reprezentarea n
complement fa de doi. Valorile de ntregi scuri reprezentabile sunt
de la -32768 la 32767 iar valoarea implicit este 0 reprezentat pe doi
octei.
Pentru declararea variabilelor de tip ntreg scurt n Java se folosete
cuvntul rezervat short, ca n exemplele urmtoare:
short i, j;
short valoareNuPreaMare;
int salariu;
unde s este semnul +1 sau -1, m este partea care specific cifrele
reprezentative ale numrului, numit i mantis, un ntreg pozitiv
mai mic dect 224 iar e este un exponent ntreg ntre -149 i 104.
Valoarea implicit pentru variabilele flotante este 0.0f. Pentru
declararea unui numr flotant, Java definete cuvntul
rezervat float. Declaraiile se fac ca n exemplele urmtoare:
float procent;
float noi, ei;
58
unde s este semnul +1 sau -1, m este mantisa, un ntreg pozitiv mai
mic dect 253 iar e este un exponent ntreg ntre -1045 i 1000.
Valoarea implicit n acest caz este 0.0d.
Pentru a declara flotani dubli, Java definete cuvntul
rezervat double ca n:
double distanaPnLaLun;
64
65
};
sau
float [][]multiTablou = new float[3][4];
int dimensiune1 = multiTablou[2].length;
// dimensiune1 primete valoarea 4
int dimensiune2 = multiTablou.length;
// dimensiune2 primete valoarea 3 ^
Figura 5.1 Elementele tabloului sunt de tip referin, iniializate implicit la valoarea null.
Figura 5.2 Noile tablouri sunt referite din interiorul tabloului original. Elementele noilor
tablouri sunt caractere.
Figura 5.3 Variabilele de tip referin caractere[0] i tablouDeCaractere trimit spre acelai
tablou rezervat n memorie.
5.1.6 Conversii
Operaiile definite n limbajul Java au un tip bine precizat de
argumente. Din pcate, exist situaii n care nu putem transmite la
apelul acestora exact tipul pe care compilatorul Java l ateapt. n
asemenea situaii, compilatorul are dou alternative: fie respinge
orice operaie cu argumente greite, fie ncearc s converteasc
argumentele ctre tipurile necesare. Desigur, n cazul n care
conversia nu este posibil, singura alternativ rmne prima.
n multe situaii ns, conversia este posibil. S lum de exemplu
tipurile ntregi. Putem s convertim ntotdeauna un ntreg scurt la
un ntreg. Valoarea rezultat va fi exact aceeai. Conversia invers
ns, poate pune probleme dac valoarea memorat n ntreg
depete capacitatea de memorare a unui ntreg scurt.
68
byte
short
69
la char
short la byte sau char
char la byte sau short
int la byte, short sau char
long la byte, short char, sau int
float la byte, short, char, int sau long
double la byte, short, char, int, long sau
byte
float.
Da
Nu
Nu
Nu
Nu Nu
Nu
Nu
char
Nu
Da
Da
Da
Nu Nu
Nu
Nu
byte
Nu
Da
Da
Nu
Nu Nu
Nu
Nu
short
Nu
Da
Da
Da
Nu Nu
Nu
Nu
int
Nu
Da
Da
Da
Da Nu
Nu
Nu
long
Nu
Da
Da
Da
Da
Da
Nu
Nu
float
Nu
Da
Da
Da
Da
Da
Da
Nu
71
double
Nu
Da
Da
Da
Da
Da
Da
Da
Tabloul 5.1 Conversiile posibile ntr-o operaie de atribuire cu tipuri primitive. Coloanele
reprezint tipurile care se atribuie iar liniile reprezint tipul de variabil ctre care se face
atribuirea.
T este o clas
care este final
T este o
interfa
T = B[] este un
tablou cu
elemente de
tipul B
S este o
clas care
nu este
final
eroare la
compilare
S trebuie s fie
Object
S este o
clas care
este final
eroare la
compilare
eroare la
compilare
S este o
interfa
T trebuie s
implementeze
interfaa S
T trebuie s
implementeze
interfaa S
T trebuie s
fie o
subinterfa
a lui S
eroare la
compilare
S = A[] este
un tablou
cu
elemente
de tipul A
eroare la
compilare
eroare la
compilare
eroare la
compilare
A sau B sunt
acelai tip
primitiv sau A
este un tip
referin i B
poate fi
atribuit lui A
Tabloul 5.2 Conversiile posibile la atribuirea unei valori de tipul T la o variabil de tipul S.
T este o clas
care este final
T este o
interfa
T = B[] este un
tablou cu
elemente de
tipul B
S este o
clas care
nu este
final
Totdeauna
corect la
compilare
S trebuie s fie
Object
S este o
clas care
este final
S trebuie s
implementeze
interfaa T
eroare la
compilare
T trebuie s
implementeze
interfaa S
Totdeauna
corect la
compilare
eroare la
compilare
eroare la
compilare
eroare la
compilare
A sau B sunt
acelai tip
primitiv sau A
este un tip
referin i B
poate fi
convertit cu un
cast la A
S este o
interfa
Totdeauna
corect la
compilare
Tabloul 5.3 Cazurile posibile la convertirea unei referine de tip T ntr-o referin de tip S.
75
Capitolul V
5.2 Expresii
5.2.1 Valoarea i tipul unei expresii
5.2.2 Ordinea de evaluare
5.2.3 Operatori
5.2.3.1 Operatori unari
5.2.3.1.1 Operatorii de preincrementare i postincrementare
5.2.3.1.2 Operatorul + unar
5.2.3.1.3 Operatorul - unar
5.2.3.1.4 Operatorul de complementare
5.2.3.1.5 Operatorul de negare logic
5.2.3.1.6 Casturi
5.2.3.2 Operatori binari
5.2.3.2.1 Operatori multiplicativi: *, /, %
5.2.3.2.2 Operatori aditivi: +, -, concatenare pentru iruri de
caractere
5.2.3.2.3 Operatori de iftare: >>, <<, >>>
5.2.3.2.4 Operatori relaionali: <, >, <=, >=, instanceof
5.2.3.2.5 Operatori de egalitate: ==, !=
5.2.3.2.6 Operatori la nivel de bit: &, |, ^
5.2.3.2.7 Operatori logici: &&, ||
5.2.3.3 Operatorul condiional ?:
5.2.3.4 Operaii ntregi
5.2.3.5 Operaii flotante
5.2.3.6 Apeluri de metode
5.2.1 Valoarea i tipul unei expresii
Fiecare expresie a limbajului Java are un rezultat i un tip.
Rezultatul poate fi:
o valoare
o variabil
nimic
76
( i++ ) + i
( a = b )[i]
77
new int[i++][i]
5.2.3 Operatori
5.2.3.1 Operatori unari
Operatorii unari se aplic ntotdeauna unui singur operand. Aceti
operatori sunt, n general exprimai naintea operatorului asupra
cruia se aplic. Exist ns i dou excepii, operatorii de
incrementare i decrementare care pot apare i nainte i dup
operator, cu semnificaii diferite.
Operatorii unari sunt urmtorii:
preincrement
-- predecrement
++ postincrement
-- postdecrement
+ unar
- unar
~ complementare
! negaie logic
cast
++
int i = 5;
int j = --i;
79
6.6
pentru f i pentru g.
80
Operatori
Operatori
caractere
Operatori
Operatori
Operatori
Operatori
Operatori
multiplicativi: *, /, %
aditivi: +, -, + (concatenare) pentru iruri de
de iftare: >>, <<, >>>
relaionali: <, >, <=, >=,
de egalitate: ==, !=
la nivel de bit: &, |, ^
logici: &&, ||
instanceof
81
Dup cum observai, operanzii sunt convertii mai nti la tipul cel
mai puternic, prin promovare aritmetic, i apoi se execut operaia.
Rezultatul este de acelai tip cu tipul cel mai puternic.
n cazul operatorului pentru restul mpririi, dac lucrm cu
numere flotante, rezultatul se calculeaz n felul urmtor: se
calculeaz de cte ori este cuprins cel de-al doilea operand n primul
(un numr ntreg de ori) dup care rezultatul este diferena care mai
rmne, ntotdeauna mai mic strict dect al doilea operand.
5.2.3.2.2 Operatori aditivi: +, -, concatenare pentru iruri de caractere
82
2040
11111111 -> 00000111 11111000
7
11111111 -> 00000000 00000111
>>>
>>>
>>>
>>>
>>>
-1 == 0x00000001
-2 == 0x00000003
-3 == 0x00000007
3 == 0x1fffffff
5 == 0x07ffffff ^
S mai observm c
String
Object.
83
&
&
&
&
1
0
1
0
==
==
==
==
1
0
0
0
&
00101111
01110110
rezultatul este:
00100110
47,
al doilea
118
iar rezultatul
38,
deci:
47 & 118 == 38
84
|
|
|
|
1
0
1
0
==
==
==
==
1
1
1
0
iar tabela de adevr pentru operaia logic de sau exclusiv (^) este:
1
1
0
0
^
^
^
^
1
0
1
0
==
==
==
==
0
1
1
0
n cazul operatorului && este evaluat mai nti operandul din stnga.
Dac acesta este fals, operandul din dreapta nu mai este evaluat,
pentru c oricum rezultatul este fals. Acest lucru ne permite s
testm condiiile absolut necesare pentru corectitudinea unor
operaii i s nu executm operaia dect dac aceste condiii sunt
ndeplinite.
De exemplu, dac avem o referin i dorim s citim o valoare de
variabil din obiectul referit, trebuie s ne asigurm c referina
este diferit de null. n acest caz, putem scrie:
String s = "sir de caractere";
85
null,
null,
100.4.
int a[] = { 1, 2, 3, 4, 5 };
int b[] = { 10, 20, 30 };
int k = ( ( a.length < b.length ) ? a : b )[0];
86
10.
87
este adevrat, unde +0.0 este zeroul pozitiv iar -0.0 este zeroul
negativ. Cele dou valori sunt definite n standardul IEEE 754.
n alte operaii ns, zero pozitiv difer de zero negativ. De exemplu
1.0 / 0.0 este infinit pozitiv iar 1.0 / -0.0 este infinit negativ.
5.2.3.6 Apeluri de metode
La apelul unei metode, valorile ntregi nu sunt automat extinse la
ntreg sau la ntreg lung ca la operaii. Asta nseamn c, dac un
operand este transmis ca ntreg scurt de exemplu, el rmne ntreg
scurt i n interiorul metodei apelate.
88
Capitolul V
5.3 Instruciuni
5.3.1 Blocuri de instruciuni
5.3.1.1 Declaraii de variabile locale
5.3.2 Tipuri de instruciuni
5.3.2.1 Instruciuni de atribuire
5.3.2.1.1 Atribuire cu operaie
5.3.2.1.2 Atribuiri implicite
5.3.2.2 Instruciuni etichetate
5.3.2.3 Instruciuni condiionale
5.3.2.3.1 Instruciunea if
5.3.2.3.2 Instruciunea switch
5.3.2.4 Instruciuni de ciclare
5.3.2.4.1 Instruciunea while
5.3.2.4.2 Instruciunea do
5.3.2.4.3 Instruciunea for
5.3.2.5 Instruciuni de salt
5.3.2.5.1 Instruciunea break
5.3.2.5.2 Instruciunea continue
5.3.2.5.3 Instruciunea return
5.3.2.5.4 Instruciunea throw
5.3.2.6 Instruciuni de protecie
5.3.2.6.1 Instruciunea try
5.3.2.6.2 Instruciunea synchronized
5.3.2.7 Instruciunea vid
5.3.1 Blocuri de instruciuni
Un bloc de instruciuni este o secven, eventual vid, de
instruciuni i declaraii de variabile locale. Aceste instruciuni se
89
{
int x = 5;
}
}
90
{
{
int x = 3;
{
int x = 5;
}
}
Figura 5.4 Reprezentarea grafic a domeniilor de existen a variabilelor incluse unul ntr-altul.
91
n acest caz, domeniile n care sunt definite cele dou variabile sunt
complet disjuncte i compilatorul nu va avea nici o dificultate n a
identifica la fiecare referire a unei variabile cu numele x despre care
variabil este vorba. S mai observm c, n cel de-al doilea
exemplu, referirea variabilelor x n blocul mare, n afara celor dou
subblocuri este o eroare de compilare.
n cazul n care blocul mare este blocul de implementare al unei
metode i metoda respectiv are parametri, aceti parametri sunt
luai n considerare la fel ca nite declaraii de variabile care apar
chiar la nceputul blocului. Acest lucru face ca numele parametrilor
s nu poat fi folosit n nici o declaraie de variabil local din
blocul de implementare sau subblocuri ale acestuia.
n realitate, o variabil local poate fi referit n interiorul unui bloc
abia dup declaraia ei. Cu alte cuvinte, domeniul de existen al
unei variabile locale ncepe din punctul de declaraie i continu
pn la terminarea blocului.
Astfel, urmtoarea secven de instruciuni:
{
x = 4;
int x = 3;
}
92
94
&=, |=, ^= ^
Valoare: Instruciune
default:
Instruciune
95
true,
if
n care partea
else
lipsete:
int x = 3;
if( x == 3 )
x *= 7;
96
x = 3;
y = 5;
y != 0 && x / y == 2 )
4;
switch(
Expresie ) {
switch:
int x = 4;
int y = 0;
switch( x + 1 ) {
case 3:
x += 2;
y++;
case 5:
x = 11;
y++;
default:
x = 4;
y += 3;
}
98
99
else
n acest caz, i este cnd par cnd impar i se execut alternativ cele
dou ramuri din if. Desigur, comportarea descris este valabil
dac valoarea luii nu este modificat n interiorul uneia dintre
ramuri.
5.3.2.4.1 Instruciunea while
100
Test ) Corp
Corp
while(
Test ) ;
int i = 0, j = 1;
103
Test ) {
Corp
Reluare ;
}
n fine, schema urmtoare reprezint funcionarea unei bucle
for:
break
Identificator;
105
106
do {
i++;
continue;
i++;
} while( i < 10 );
while
i reluarea
107
108
try:
try
( Expresie ) Instruciune
110
Iat i un exemplu:
int x = 3;
if( x == 5 ) ; else x = 5;
111
Capitolul VI
Obiecte Java
6.1 Declaraia unei noi clase de obiecte
Pasul 1: Stabilirea conceptului reprezentat de clasa de obiecte
Pasul 2: Stabilirea numelui clasei de obiecte
Pasul 3: Stabilirea superclasei
Pasul 4: Stabilirea interfeelor pe care le respect clasa
Pasul 5: Stabilirea modificatorilor clasei
Pasul 6: Scrierea corpului declaraiei
Stop: Forma general a unei declaraii de clas
6.2 Variabilele unei clase
6.2.1
6.2.2
6.2.3
6.2.4
6.2.5
Modificatori
Protecie
Accesarea unei variabile
Vizibilitate
Variabile predefinite: this i super
Clauze throws
Apelul metodelor
Valoarea de retur a unei metode
Vizibilitate
6.5.1 constructori
6.5.2 Finalizatori
6.5.3 Crearea instanelor
6.6 Derivarea claselor
6.7 Interfee
n primul rnd s observm c, atunci cnd scriem programe n
Java nu facem altceva dect s definim noi i noi clase de obiecte.
Dintre acestea, unele vor reprezenta nsi aplicaia noastr n timp
ce altele vor fi necesare pentru rezolvarea problemei la care lucrm.
Ulterior, atunci cnd dorim s lansm aplicaia n execuie nu va
trebui dect s instaniem un obiect reprezentnd aplicaia n sine
i s apelm o metod de pornire definit de ctre aplicaie, metod
care de obicei are un nume i un set de parametri bine fixate.
Totui, numele acestei metode depinde de contextul n care este
lansat aplicaia noastr.
Aceast abordare a construciei unei aplicaii ne spune printre altele
c vom putea lansa oricte instane ale aplicaiei noastre dorim,
pentru c fiecare dintre acestea va reprezenta un obiect n memorie
avnd propriile lui valori pentru variabile. Execuia instanelor
diferite ale aplicaiei va urma desigur ci diferite n funcie de
interaciunea fiecreia cu un utilizator, eventual acelai, i n
funcie de unii parametri pe care i putem defini n momentul crerii
fiecrei instane.
113
abstract
extends
implements
final
public
}*
class
NumeClas
NumeSuperclas ]
NumeInterfa [ , NumeInterfa ]* ]
{ [ CmpClas ]* }
116
privat
protejat
public
prietenoas
117
118
sau
super.NumeVariabil
119
throws
pot s lipseasc.
120
122
privat
protejat
public
prietenoas
124
NumeTip [, NumeTip]*
sau, alternativ:
double aleator = java.lang.Math.random();
Cea de-a doua cale de acces este existena unei instane a clasei
respective. Prin aceast instan putem accesa metodele care nu
sunt declarate statice, numite uneori i metode ale instanelor
clasei. Aceste metode au nevoie de o instan a clasei pentru a
putea lucra, pentru c folosesc variabile non-statice ale clasei sau
apeleaz alte metode non-statice. Metodele primesc acest obiect ca
pe un parametru ascuns.
De exemplu, avnd o instan a clasei Object sau a unei subclase a
acesteia, putem obine o reprezentare sub form de ir de caractere
prin:
Object obiect = new Object();
String sir = obiect.toString();
void a() { }
Metoda static abs din clasa Math care primete un parametru ntreg
returneaz tot un ntreg. n exemplul nostru,
instruciunea return este corect pentru c exist o cale de conversie
de la ntreg la ntreg lung, conversie care este apelat automat de
compilator nainte de ieirea din metod.
n schimb, n exemplul urmtor:
int abs( long valoare ) {
return Math.abs( valoare );
}
127
if( )
return;
void a() { }
}
class B extends A {
void b() {
a();
c();
}
void c() { .. }
void a() { }
}
class B extends A {
void a() { .. }
void c() {
a();// metoda a din clasa B
A.a();// metoda a din clasa A
128
BlocDeInstruciuni
129
throws.
[Parametri] );
super(
[Parametri] );
super();
6.5.2 Finalizatori
n Java nu este nevoie s apelm n mod explicit distrugerea unei
instane atunci cnd nu mai este nevoie de ea. Sistemul ofer un
mecanism de colectare a gunoaielor care recunoate situaia n care
o instan de obiect sau un tablou nu mai sunt referite de nimeni i
le distruge n mod automat.
Acest mecanism de colectare a gunoaielor ruleaz pe un fir de
execuie separat, de prioritate mic. Nu avem nici o posibilitate s
aflm exact care este momentul n care va fi distrus o instan.
Totui, putem specifica o funcie care s fie apelat automat n
momentul n care colectorul de gunoaie ncearc s distrug
obiectul.
Aceast funcie are nume, numr de parametri i tip de valoare de
retur fixe:
void
finalize()
131
Exemple de creare:
A o1 = new A();
B o2 = new B();
class C extends B {
String valoare;
C( String val ) {
// aici exist apel implicit
// al lui super(), adic B()
valoare = val;
}
C( int val ) {
this( String.valueOf( val ) );
}
}
C o3 = new C( "Vasile" );
C o4 = new C( 13 );
132
SubClas
extends
SuperClas
class A {
int a = 1;
void unu() {
System.out.println( a );
}
}
class B extends A {
double a = Math.PI;
void unu() {
System.out.println( a );
}
void doi() {
System.out.println( A.a );
}
void trei() {
unu();
super.unu();
}
}
va afia dou numere diferite, mai nti 1 i apoi PI. Aceasta din
cauz c cel de-al doilea element din tablou este, n timpul
execuiei, de tip referin la o instan a clasei B chiar dac la
compilare este de tipul referin la o instan a clasei A.
Acest mecanism se numete legare trzie, i nseamn c metoda
care va fi efectiv apelat este stabilit doar n timpul execuiei i nu
la compilare.
Dac nu declarm nici o superclas n definiia unei clase, atunci se
consider automat c noua clas deriv direct din clasa Object,
motenind toate metodele i variabilele acesteia.
6.7 Interfee
O interfa este n esen o declaraie de tip ce const dintr-un set
de metode i constante pentru care nu s-a specificat nici o
implementare. Programele Java folosesc interfeele pentru a suplini
lipsa motenirii multiple, adic a claselor de obiecte care deriv din
dou sau mai multe alte clase.
Sintaxa de declaraie a unei interfee este urmtoarea:
Modificatori
interface
NumeInterf [
extends
[Interfa][, Interfa]*]
Corp
Modificatorii unei interfee pot fi doar cuvintele
rezervate public i abstract. O interfa care este public poate fi
accesat i de ctre alte pachete dect cel care o definete. n plus,
fiecare interfa este n mod implicit abstract.
Modificatorul abstract este permis dar nu obligatoriu.
Numele interfeelor trebuie s fie identificatori Java. Conveniile de
numire a interfeelor le urmeaz n general pe cele de numire a
claselor de obiecte.
Interfeele, la fel ca i clasele de obiecte, pot avea subinterfee.
Subinterfeele motenesc toate constantele i declaraiile de metode
135
ale interfeei din care deriv i pot defini n plus noi elemente.
Pentru a defini o subinterfa, folosim o clauz extends. Aceste clauze
specific superinterfaa unei interfee. O interfa poate avea mai
multe superinterfee care se declar separate prin virgul dup
cuvntul rezervatextends. Circularitatea definiiei subinterfeelor nu
este permis.
n cazul interfeelor nu exist o rdcin comun a arborelui de
derivare aa cum exist pentru arborele de clase, clasa Object.
n corpul unei declaraii de interfa pot s apar declaraii de
variabile i declaraii de metode. Variabilele sunt implicit statice i
finale. Din cauza faptului c variabilele sunt finale, este obligatoriu
s fie specificat o valoare iniial pentru aceste variabile. n plus,
aceast valoare iniial trebuie s fie constant (s nu depind de
alte variabile).
Dac interfaa este declarat public, toate variabilele din corpul
su sunt implicit declarate publice.
n ceea ce privete metodele declarate n interiorul corpului unei
interfee, acestea sunt implicit declarate abstracte. n plus, dac
interfaa este declarat public, metodele din interior sunt implicit
declarate publice.
Iat un exemplu de declaraii de interfee:
public interface ObiectSpatial {
final int CUB = 0;
final int SFERA = 1;
double greutate();
double volum();
double raza();
int tip();
}
public interface ObiectSpatioTemporal extends ObiectSpatial {
void centrulDeGreutate( long moment,
double coordonate[] );
long momentInitial();
long momentFinal();
}
136
137
coordonate[0] = x;
coordonate[1] = y;
coordonate[2] = z;
return true;
}
long momentInitial() {
return nastere;
}
long momentFinal() {
return moarte;
}
int ceCuloare() {
return culoare;
}
double cePret() {
return pret;
}
}
138
139
Capitolul VII
Modele de programare
Un nou limbaj de programare nu are anse s se impun fr s
ofere, pe lng sintaxa propriu-zis un set de biblioteci sau o
ierarhie de clase coerent i ct mai general. Atunci cnd limbajul
C a fost prezentat pentru prima dat, mpreun cu el a fost
prezentat i biblioteca standard de intrare ieire. Primul program C
pe care l-am nvat coninea deja apelul:
printf( "hello, world!" );
140
metoda main fiind de tip static, nu poate apela dect variabile statice.
De obicei ns, metoda main nu face nimic altceva dect s-i
prelucreze parametrul dup care s creeze o serie de obiecte care
vor controla execuia ulterioar a aplicaiei.
Singurul parametru al metodei main este un tablou care conine
argumentele aflate pe linia de comand n momentul apelului. Nu
este necesar transmiterea numrului de argumente care au fost
gsite pe linia de comand pentru c tablourile Java conin n
interior informaii relative la numrul de elemente. Acest numr de
elemente se poate obine prin accesarea variabilei length din
interiorul tabloului ca n exemplul urmtor care listeaz parametrii
de pe linia de comand la lansarea unei clase:
public class Arguments {
public static void main( String args[] ) {
for( int i = 0; i < args.length; i++ ) {
System.out.println( args[i] );
}
}
}
Iat un exemplu de rulare a acestei aplicaii:
>java Arguments unu doi trei
unu
doi
trei
> ^
HEIGHT=25>
143
144
145
146
Putei rula apletul de mai sus pentru a vedea care este ordinea n
care sunt apelate aceste metode de ctre navigator. Apletul de mai
sus produce ieiri la consol (o fereastr text) i nu n fereastra
apletului. Dac nu vedei consola, ncercai s cutai prin
meniurile navigatorului opiunea de afiare a consolei Java.
Netscape de exemplu are o astfel de opiune n meniul OptionsShow Java console.
Din cele spuse pn acum se poate deduce c apleturile Java nu au
o via proprie, ele fiind doar apelate din cnd n cnd de navigator.
Ceea ce nu este ntocmai adevrat pentru c biblioteca standard de
clase Java ofer suport pentru aplicaii care folosesc mai multe fire
de execuie. Apleturile pot astfel crea fire de execuie care s lucreze
independent fa de navigator.
--
HEIGHT=150>
148
Capitolul VII
Structura programelor
8.1
8.2
8.3
8.4
Pachete de clase
Importul claselor
Fiiere surs
Compilare i execuie
149
i aa mai departe.
numeClas ;
unde numele clasei include i pachetul din care aceasta face parte.
De exemplu:
import java.awt.Graphics;
import java.applet.Applet;
numePachet.*;
De exemplu:
import java.awt.*;
numePachet;
150
main
151
152
Capitolul IX
Fire de execuie i sincronizare
9.1
9.2
9.3
9.4
9.5
9.6
9.7
9.8
154
public TestFirNou {
public static void main( String[] ) {
new FirNou( "Primul" ).start();
}
}
}
class FirNou extends Oclasa implements Runnable {
public void run() {
for( int i = 0; i < 100; i++ ) {
System.out.println( "pasul " + i );
}
}
}
public class TestFirNou {
public static void main( String argumente[] ) {
new Thread( new FirNou() ).start();
// Obiectele sunt create i folosite imediat
// La terminarea instruciunii, ele sunt automat
// eliberate nefiind referite de nimic
}
}
try {
sleep( 1000 ); // o secund
} catch( InterruptedException ) {
try {
firDeExecutie.start();
} catch( ThreadDeath td ) {
// curenie
throw td; // se arunc obiectul mai departe
// pentru a servi la distrugerea
// firului de execuie
}
try {
firDeExecutie.start();
} finally {
..// curenie
}
face parte din acest grup. n continuare, ori de cte ori crem un
nou fir de execuie, acesta va face parte din acelai grup de fire de
execuie ca i firul de execuie din interiorul cruia a fost creat, n
afar de cazurile n care n constructorul firului specificm explicit
altceva.
ntr-un grup de fire de execuie putem defini nu numai fire dar i
alte grupuri de execuie. Se creeaz astfel o arborescen a crei
rdcin este grupul principal de fire de execuie.
Pentru a specifica pentru un fir un nou grup de fire de execuie,
putem apela constructorii obinuii dar introducnd un prim
parametru suplimentar de tipThreadGroup . De exemplu, putem folosi
urmtorul cod:
ThreadGroup tg = new ThreadGroup( "Noul grup" );
Thread t = new Thread( tg, "Firul de executie" );
Acest nou fir de execuie va face parte dintr-un alt grup de fire dect
firul principal. Putem afla grupul de fire de execuie din care face
parte un anumit fir apelnd metoda getThreadGroup , ca n secvena:
Thread t = new Thread( "Firul de Executie" );
ThreadGroup tg = t.getThreadGroup();
public listeazaFire {
ThreadGroup grup = Thread.currentThread().getThreadGroup();
int numarFire = grup.activeCount();
Thread fire[] = new Thread[numarFire];
grup.enumerate( fire );
for( int i = 0; i < numar; i++ ) {
System.out.println( fire[i].toString() );
}
}
9.6 Sincronizare
n unele situaii se poate ntmpla ca mai multe fire de execuie s
vrea s acceseze aceeai variabil. n astfel de situaii, se pot
produce ncurcturi dac n timpul unuia dintre accese un alt fir de
execuie modific valoarea variabilei.
Limbajul Java ofer n mod nativ suport pentru protejarea acestor
variabile. Suportul este construit de fapt cu granulaie mai mare
dect o singur variabil, protecia fcndu-se la nivelul obiectelor.
Putem defini metode, n cadrul claselor, care sunt sincronizate.
Pe o instan de clas, la un moment dat, poate lucra o singur
metod sincronizat. Dac un alt fir de execuie ncearc s apeleze
aceeai metod pe aceeai instan sau o alt metod a clasei de
asemenea declarat sincronizat, acest al doilea apel va trebui s
atepte nainte de execuie eliberarea instanei de ctre cealalt
metod.
n afar de sincronizarea metodelor, se pot sincroniza i doar
blocuri de instruciuni. Aceste sincronizri se fac tot n legtur cu
o anumit instan a unei clase. Aceste blocuri de instruciuni
sincronizate se pot executa doar cnd instana este liber. Se poate
ntmpla ca cele dou tipuri de sincronizri s se amestece, n
sensul c obiectul poate fi blocat de un bloc de instruciuni i toate
metodele sincronizate s atepte, sau invers.
Declararea unui bloc de instruciuni sincronizate se face prin:
synchronize
( Instan ) {
Instruciuni
}
162
9.7 Un exemplu
Exemplul urmtor implementeaz soluia urmtoarei probleme:
ntr-o ar foarte ndeprtat triau trei nelepi filozofi. Aceti trei
nelepi i pierdeau o mare parte din energie certndu-se ntre ei
pentru a afla care este cel mai nelept. Pentru a trana problema o
dat pentru totdeauna, cei trei nelepi au pornit la drum ctre un
al patrulea nelept pe care cu toii l recunoteau c ar fi mai bun
dect ei.
Cnd au ajuns la acesta, cei trei i-au cerut s le spun care dintre
ei este cel mai nelept. Acesta, a scos cinci plrii, trei negre i
dou albe, i li le-a artat explicndu-le c i va lega la ochi i le va
pune n cap cte o plrie, cele dou rmase ascunzndu-le. Dup
aceea, le va dezlega ochii, i fiecare dintre ei va vedea culoarea
plriei celorlali dar nu i-o va putea vedea pe a sa. Cel care i va
da primul seama ce culoare are propria plrie, acela va fi cel mai
nelept.
Dup explicaie, neleptul i-a legat la ochi, le-a pus la fiecare cte o
plrie neagr i le-a ascuns pe celelalte dou. Problema este aceea
de a descoperi care a fost raionamentul celui care a ghicit primul
c plria lui este neagr.
Programul urmtor rezolv problema dat n felul urmtor: Fiecare
nelept privete plriile celorlali doi. Dac ambele sunt albe,
problema este rezolvat, a lui nu poate fi dect neagr. Dac vede o
plrie alb i una neagr, atunci el va trebui s atepte puin s
vad ce spune cel cu plria neagr. Dac acesta nu gsete soluia,
nseamn c el nu vede dou plrii albe, altfel ar fi gsit imediat
rspunsul. Dup un scurt timp de ateptare, neleptul poate s fie
sigur c plria lui este neagr.
n fine, dac ambele plrii pe care le vede sunt negre, va trebui s
atepte un timp ceva mai lung pentru a vedea dac unul dintre
concurenii si nu ghicete plria. Dac dup scurgerea timpului
nici unul nu spune nimic, nseamn c nici unul nu vede o plrie
alb i una neagr. nseamn c propria plrie este neagr.
Desigur, raionamentul pleac de la ideea c ne putem baza pe
faptul c toi nelepii gndesc i pot rezolva probleme uoare. Cel
163
care ctig a gndit doar un pic mai repede. Putem simula viteza
de gndiri cu un interval aleator de ateptare pn la luarea
deciziilor. n realitate, intervalul nu este aleator ci dictat de viteza de
gndire a fiecrui nelept.
Cei trei nelepi sunt implementai identic sub form de fire de
execuie. Nu ctig la fiecare rulare acelai din cauza caracterului
aleator al implementrii. neleptul cel mare este firul de execuie
principal care controleaz activitatea celorlalte fire i le servete cu
date, culoarea plriilor, doar n msura n care aceste date trebuie
s fie accesibile. Adic nu se poate cere propria culoare de plrie.
Culoarea iniial a plriilor se poate rescrie din linia de comand.
import java.awt.Color;
// clasa Filozof implementeaz comportamentul
// unui concurent
class Filozof extends Thread {
// prerea concurentului despre culoarea
// plriei sale. Null dac nc nu i-a
// format o prere.
Color parere = null;
Filozof( String nume ) {
super( nume );
}
public void run() {
// concurentii firului curent
Filozof concurenti[] = new Filozof[2];
// temporar
Thread fire[] = new Thread[10];
int numarFire = enumerate( fire );
for( int i = 0, j = 0; i < numarFire &&
j < 2; i++ ) {
if( fire[i] instanceof Filozof &&
fire[i] != this ) {
concurenti[j++] = (Filozof)fire[i];
}
}
while( true ) {
Color primaCuloare = Concurs.culoare( this,
concurenti[0] );
Color adouaCuloare =
Concurs.culoare( this, concurenti[1] );
if( primaCuloare == Color.white &&
adouaCuloare == Color.white ) {
synchronized( this ) {
parere = Color.black;
}
} else if( primaCuloare == Color.white ){
try{
sleep( 500 );
} catch( InterruptedException e ){
};
if( Concurs.culoare( this, concurenti[1]) != concurenti[1].aGhicit()) {
synchronized( this ) {
parere = Color.black;
};
164
}
} else if( adouaCuloare == Color.white ) {
try{
sleep( (int)( Math.random()*500));
} catch( InterruptedException e ) {
};
if( Concurs.culoare(this, concurenti[0] ) != concurenti[0].aGhicit()) {
synchronized( this ) {
parere = Color.black;
};
}
} else {
try {
sleep( (int)( Math.random()*500)+500 );
} catch( InterruptedException e ) {
};
if( Concurs.culoare(this, concurenti[0]) != concurenti[0].aGhicit() &&
Concurs.culoare( this,
concurenti[1] ) !=
concurenti[1].aGhicit() ) {
synchronized( this ) {
parere = Color.black;
};
}
}
}
}
public synchronized Color aGhicit() {
return parere;
}
}
public class Concurs {
private static Color palarii[] = {
Color.black, Color.black, Color.black
};
private static Filozof filozofi[] = new Filozof[3];
public static void main( String args[] ) {
for( int i = 0; i < args.length && i <
3; i++ ) {
if( args[i].equalsIgnoreCase( "alb" ) ) {
palarii[i] = Color.white;
} else if(args[i].equalsIgnoreCase("negru")) {
palarii[i] = Color.black;
}
}
for( int i = 0; i < 3; i++ ) {
filozofi[i] = new Filozof( "Filozoful " +
( i + 1 ) );
}
for( int i = 0; i < 3; i++ ) {
filozofi[i].start();
}
System.out.println( "Concurenti:" );
for( int i = 0; i < 3; i++ ) {
System.out.println( "\t" +
filozofi[i].getName() + " "
+ (( palarii[i] == Color.white ) ?
"alb":"negru" ) );
}
gata:
while( true ) {
for( int i = 0; i < 3; i++ ) {
165
if( filozofi[i].aGhicit()==palarii[i] ) {
System.out.println(
filozofi[i].getName() +
" a ghicit." );
break gata;
}
}
}
for( int i = 0; i < 3; i++ ) {
filozofi[i].stop();
try {
filozofi[i].join();
} catch( InterruptedException e ) {};
}
}
public static Color culoare( Filozof filozof,
Filozof concurent ) {
if( filozof != concurent ) {
for( int i = 0; i < 3; i++ ) {
if( filozofi[i] == concurent ) {
return palarii[i];
}
}
}
return null;
}
} ^
166
);
167
}
public void paint( Graphics g ) {
Dimension d = size();
g.setColor( Color.red );
int xoff = d.width / n;
int yoff = d.height / n;
for( int i = 1; i < n; i++ ) {
g.drawLine( xoff * i, 0, xoff * i, d.height );
g.drawLine( 0, yoff * i, d.width, yoff * i );
}
for( int i = 0; i < n; i++ ) {
for( int j = 0; j < n; j++ ) {
if( regine[i] - 1 == j ) {
g.drawImage(queenImage,
i*xoff + 1, j*yoff + 1, this);
}
}
}
}
public String getAppletInfo() {
return "Queens by E. Rotariu";
}
} ^
168
Bibliografie
1. Dumitru Rdoiu,
HTML - Publicaii Web, Computer Press Agora SRL
2. James Gostling, Henry McGilton,
The Java Language Environment, A white paper, Sun
Microsystems, Inc.
3. David Flanagan,
Java in a Nutshell: A Desktop Quick Reference for Java
Programmers,
O'Reilly & Associates, Inc.
4. Ed Anuff,
The Java Sourcebook , Wiley Computer Publishing
5. Mike Daconta,
Java for C/C++ Programmers, Wiley Computer Publishing
6. Arthur van Hoff, Sami Shaio, Orca Starbuck,
Hooked on Java, Addison-Wesley Publishing Company
7. Laura Lemay, Charles L. Perkins,
Teach your self Java in 21 days, Sams.net Publishing
8. *** - The Java Language Specification, Sun Microsystems,
Inc.
169