Documente Academic
Documente Profesional
Documente Cultură
Cuprins ....................................................................................................................................... 1
INTRODUCERE........................................................................................................................ 2
Capitolul 1. Elementele de bază ale limbajului Java.................................................................. 8
1.1 Comentariile ..................................................................................................................... 8
1.2 Identificatori ..................................................................................................................... 9
1.3 Cuvinte cheie.................................................................................................................. 10
1.4 Literalii ........................................................................................................................... 11
1.5 Operatori......................................................................................................................... 13
1.6 Separatori ....................................................................................................................... 14
1.7 Tipuri şi variabile ........................................................................................................... 14
1.8 Declararea de variabile................................................................................................... 16
1.9 Folosirea tablourilor ....................................................................................................... 16
Capitolul 2 ................................................................................................................................ 19
2.1 Crearea unei aplicatii simple .......................................................................................... 19
2.1 Crearea unui applet......................................................................................................... 20
Capitolul 3 ................................................................................................................................ 21
3.1 Controlul executiei ......................................................................................................... 21
3.2 Siruri de caractere........................................................................................................... 23
3.3. Folosirea argumentelor de la linia de comanda............................................................. 24
Capitolul 4 ................................................................................................................................ 25
Obiecte si clase in Java............................................................................................................. 25
4.1 Crearea obiectelor .......................................................................................................... 25
4.2. Crearea claselor ............................................................................................................. 28
4.4 Membri de instanta si membri de clasa .......................................................................... 36
4.5 Clase imbricate............................................................................................................... 39
Capitolul 5 ................................................................................................................................ 47
Interfete .................................................................................................................................... 47
5.1. Ce este o interfata ? ....................................................................................................... 47
5.2. Implementarea unei interfete......................................................................................... 48
Diferente între o interfata si o clasa abstracta ...................................................................... 49
5.3 Mostenire multipla prin intermediul interfetelor............................................................ 49
5.4 Utilitatea interfetelor ...................................................................................................... 50
5.5 Crearea grupurilor de constante ..................................................................................... 51
5.6 Transmiterea metodelor ca parametri (call-back) .......................................................... 51
Capitolul 6 ................................................................................................................................ 52
Exceptii..................................................................................................................................... 52
6.1 Ce sunt exceptiile? ......................................................................................................... 52
6.2 "Prinderea" si tratarea exceptiilor................................................................................... 56
6.3 "Aruncarea" exceptiilor.................................................................................................. 58
6.4 Ierarhia claselor ce descriu exceptii ............................................................................... 59
6.5 Exceptii la executie (RuntimeException)....................................................................... 59
6.6 Crearea propriilor exceptii ............................................................................................. 60
Capitolul 7 ................................................................................................................................ 62
Pachete ..................................................................................................................................... 62
7.1 Crearea unui pachet ........................................................................................................ 62
7.2 Pachetele JDK ................................................................................................................ 64
1
INTRODUCERE
Java este un limbaj orientat pe obiecte. Trecerea de la alte paradigme de programare la
programarea orientata pe obiecte poate să fie dificilă. Java se bazează pe crearea de obiecte
care pot fi construite şi manipulate de către program. Ca şi alte limbaje , Java oferă suport
pentru scrierea şi citirea datelor de la diferite echipamente de intrare / ieşire. Java foloseşte
procese care măresc eficienţa intrărilor si ieşirilor, facilitează internaţionalizarea . Java are
posibilitatea de a lucra automat cu dealocarea memoriei adică nu este nevoie să urmăreşti
pointerii în memorie şi să faci dealocare manuală a memoriei. Această facilitate înseamnă că
un program este mai puţin vulnerabil sa se blocheze şi memoria nu poate fi intenţionat
gestionată necorespunzător.
În doar câteva luni , Java s-a mutat de la laboratoarele Sun Microsystems in centrul
scenei Word Wide Web. Niciodată înainte un limbaj de programare aşa de simplu nu a
generat intr-un timp foarte scurt aşa multă atenţie şi a captivat imaginaţia a aşa multor
programatori şi a utilizatori de calculatoare. Experţii in programarea Web consideră că Java
este cel mai semnificativ lucru care s-a dezvoltat pentru Web.
De ce Java a făcut senzaţie aşa repede ? Un răspuns ar fi că Java este independentă de
platformă şi are potenţialul să transforme Web-ul într-un mediu mult mai interactiv şi
dinamic. Alte motive ar fi că Java seamănă cu C şi C++ şi suporta populara programare
orientată pe obiecte , astfel muţi programatori cunoscători de C şi C++ au reuşit rapid să
stăpânească facilităţile puternice din Java
În continuare se vor pune bazele limbajului Java şi se arată de unde a apărut acest
limbaj şi încotro se îndreaptă. Este important de studiat Java prin prisma unui programator
C++ deoarece sintaxa şi facilităţile orientate pe obiecte sunt foarte asemănătoare.
Înainte de Java programele erau construite să ruleze sub un singur sistem de operare şi
provocarea era să se creeze programe care rulau cât mai rapid posibil. Aproape peste noapte
Java şi World Wide Web –ul au schimbat această noţiune de sisteme de operare – limbaje
bazate pe un mediu în noţiunea de platformă independentă şi limbaje pentru reţea şi sisteme.
Java reprezintă schimbarea majoră care a avut loc în industria de calculatoare. Limbaje
ca Java au mutat radical graniţa de la computere locale la servere care furnizează programe
utilizatorului.
Programatorii au acceptat aşa rapid Java deoarece oferă tot cea ce este necesar la un
limbaj modern si anume :
- facilităţi orientate pe obiect
- execuţie concurentă a proceselor (multithreadhing)
- managementul automat al memoriei
- facilităţi de lucru în reţea şi securitate
- independenţa de platformă (arhitectura neutră)
- facilităţi de lucru în Intenet / Web
2
similar cu afişarea a altor elemente cum ar fi grafica şi text dar diferenţa constă că un applet
procesează un conţinut executat dinamic in loc de date statice.
O aplicaţie Java în schimb arată asemănător cu un program în C++. Poate să ruleze
singură şi realizează diverse sarcini. Singura problemă este că la momentul actual Java este un
limbaj interpretat , şi de aceea programele scrise în Java necesită o Maşină Virtuală Java
pentru a fi executate. În viitor se preconizează dezvoltarea unor compilatoare care vor
permite ca aplicaţiile Java să ruleze mai rapid şi mai independent.
Pentru a rula applet-uri este nevoie după cum am spus de un Web browser care permite Java
sau se poate folosi utilitarul appletviewer distribuit cu Java Development Kit (JDK) de la
Sun. Pentru orice program scris în Java este nevoie de JDK deoarece oferă compilatorul
pentru compilarea applet-urilor Java o aplicaţie (javac) şi un interpretor (java) pentru a rula
aplicaţiile Java şi un debugger (jdbg). Majoritatea acestor programe rulează în linie de
comandă si sunt oarecum primitive.
Instrumentele din JDK cuprind :
- un compilator pentru limbajul Java care generează cod binar neutru arhitectural
- Maşina Virtuala Java care interpretează codul binar la rulare
- Un set de biblioteci de clase pentru a ajuta programatori Java să dezvolte aplicaţii.
Câteva din aceste biblioteci includ instrumente pentru interfaţă, I/O, crearea de
applet-uri, lucru în reţea, etc
- Un mediu Java pentru execuţie care suportă verificarea codului binar ,
multithreading şi dealocarea memoriei
- Un debugger generator de documentaţie , etc
3
Cele mai mari beneficii pe care software- ul distribuit le oferă faţă de abordarea client
server CGI sunt :
Realizarea de Interfaţă Web Interactivă . Cu applet-uri Java se pot crea pagini Web care
permit mutarea obiectelor pe ecran , vizualizare de animaţii , facilităţi multimedia ca sunetul
şi muzica .
Utilizarea resurselor Locale. Cu modelul CGI , serverul este limitat la procesarea datelor
care ii sunt transmise. Cu Java se pot scrie aplicaţii care pot cu adevărat să profite de resursele
dintr-un sistem local.
Acces îmbunătăţit la Internet. Una dintre problemele Web-ului şi a Internet-ului este că
informaţiile sunt depozitate într-un mod haotic peste tot în lume. Folosind Java se pot scrie
programe de interfaţă cu Web-ul mult mai bune , cum ar fi motoare de căutare şi se poate
îmbunătăţii accesul la Web.
Reducerea costului şi distribuirii de software. Industria soft-ului s-a transformat într-o
afacerea în care computerele rulează doar programe majore de la companii gigant . Unul
dintre motivele pentru care s-a produs acest lucru este că dea lungul anilor a crescut riscul şi
costul de producere şi distribuţie a soft-ului. Cu softul distribuit , utilizatorii pot să obţină şi
să descarce softul de care au nevoie nu fiind necesar să îl cumperi de la magazin
Securitatea în Java
Cu oportunităţile şi promisiunile software - ului distribuit vine şi riscul securităţii.
Programele care rulează pe calculatoare locale sunt acele pe care utilizatorul a decis sa le
cumpere sau să le descarce . Odată instalate pot fi verificate de viruşi şi şterse daca cauzează
probleme sistemului. Programele distribuite cum sunt şi applet - urile Java se află pe
calculatorul altuia. Când sunt rulate de fapt se descarcă cod din alt calculator la care nu ai nici
un control. Din fericire filozofia avută în vedere la proiectarea Java este securitatea. Codul
binar (bytecode) care este descărcat din reţea este trimis unui verificator de cod binar care
încearcă să elimine codul defectuos care ar putea afecta un calculator local. Deoarece Java nu
foloseşte pointerii sau rutine programabile de alocare a memorie codul Java este puţin
probabil să blocheze un calculator datorită unei operaţii de alocare greşită a memoriei.
Pentru a mări securitatea Java dispune de clase care verifică conflictele legate de
securitate. Ca măsură finală Java permite utilizatorului configurarea detaliată a securităţii. De
exemplu un utilizator poate să specifice exact ce directoare poate sa scrie sau să citească un
applet.
Java şi C++
Java este foarte asemănătoare cu limbajul C++. Dacă se dispune de cunoştinţe de C++
migrarea spre Java va fi uşoară. Dacă există cunoştinţe de începător atât pentru C++ şi Java
trebuie să ajungi să înţelegi natura orientată pe obiecte a limbajului Java.
Pentru început să vedem câteva probleme cheie a programării orientată pe obiecte. În primul
rând , C++ nu este un limbaj orientat pe obiecte (OO) „adevărat “ dar Java este mult mai
aproape de acest lucru. Aceasta deoarece totul în Java este o clasă şi toate apelurile de metode
sunt făcute prin invocarea unei metode a unui obiect dintr-o clasă Java. În C++ se pot folosi
funcţii de sine – stătătoare , fişiere header, variabile globale etc. Singurul lucru care nu se
găseşte în clasă în Java este interfaţa . Oricum interfeţele sunt folosite ca şi clasele dar fără
implementare.
4
Această natură strictă a OO înseamnă că nu se poate converti cod C++ foarte uşor.
Ce lipseşte ?
Unul din scopurile creatorilor Java a fost să studieze toate celelalte limbaje de
programare şi să scoată cele mai bune facilităţi din fiecare. Sintaxa adoptată pentru limbajul
Java este importată din limbajul C/C++ . Multe din facilităţile limbajului C++ nu au fost
implementate din motive de securitate deoarece limbajul Java este destinat Web-ului Alte
facilităţi au fost omise deoarece erau prea dificil de utilizat sau erau nefolositoare.
Eliminarea pointerilor
Aritmetica pointerilor este cel mai mare blestem pentru cei care urăsc C++. Pentru cei puţin
dintre programatori care stăpânesc pointerii, vă salutăm. Pentru restul dintre noi, bine c-am
scăpat. Principalul motiv pentru care pointeri nu sunt folosiţi în Java este securitatea. Dacă
applet-urile Java au posibilitatea să acceseze memoria direct , ar putea să cauzeze foarte uşor
probleme grave. Sunt câteva sarcini care necesită pointeri . Dar datorită faptului că în Java nu
există trebuie găsite posibilităţi de a trata aceste lucruri. În Java obiectele sunt transmise ca
argumente direct in loc să se folosească transmiterea unui pointer la obiect . Trebuie de
asemenea să foloseşti indici ca să utilizezi tablouri decât să acceseze valori direct.
Utilizatorii de C++ consideră că fişierele header sunt foarte folositoare. Cu toate acestea dacă
se observă mai îndeaproape la modul cum folosesc majoritatea programatorilor fişierele
header se va observa că cea mai mare utilizare a fişierelor header este pentru documentare şi
prototipare. Pentru a examina interfaţa unei funcţii se examinează fişierul header. Prin simpla
examinare a hederului unei clase din C++ se poate distinge mult despre cea ce face o clasă
fără să se vadă nimic din implementare.
În Java nu se poate realiza acest lucru din vreme ce implementarea pentru clasă şi
metode trebuie să se realizez în acelaşi loc. În Java implementarea întotdeauna urmează după
declaraţie. Bineînţeles că se poate documenta codul cu comentarii dar codul poate să fie pe
mai multe pagini. Nu este întotdeauna uşor să te uiţi la codul unei clase Java şi să înţelegi ce
face . Se pune întrebarea de ce Java nu foloseşte headere . În primul rând nu este posibil să
foloseşti o bibliotecă care declară o metodă dar care nu o implementează. În al doilea rând
este mult mai dificil să programezi cu fişiere care nu sunt sincronizate cu implementarea
5
simple şabloane pentru o clasă să le urmeze. Ele conţin declaraţii metodelor fără
implementare . orice clasă care implementează o interfaţă trebuie să folosească metodele
declarate în interfaţă.
Interfeţele funcţionează bine, dar au câteva limitări. Cel mai mare neajuns este ca
trebuie să scrie cod pentru fiecare metodă pe care interfaţa o declară. Moştenirea multiplă în
C++ permitea să se suprascrie metodele pe care le doreşti şi apoi poţi să foloseşti
implementarea părinte pentru alte scopuri . Interfeţele sunt mult mai uşor de înţeles şi folosi
decât moştenirea multiplă. Cu o strategie de programare corectă se poate obţine aproape toată
funcţionalitatea moştenirii multiple . Şi cu speranţa că nu vor fi toate problemele.
Ce este nou ?
Atunci când se termină folosirea unei resurse în C++, trebuie explicit să ii spui la calculator
când să elibereze memoria care o foloseşte. Acest lucru se realizează cu pointeri. Din
moment ce Java nu foloseşte pointeri din motive de securitate , are nevoie de un mod de a
curăţa resursele când nu mai sunt necesare . Aici intervine colectarea informaţiei inutile.
Colectarea informaţiei inutile este un mediu fir de execuţie (thread ) în momentul
rulării (run -time) care menţine o evidenţă a toate părţile programului şi automat dealocă
memoria folosită când aceasta nu mai este necesară . De exemplu atunci când se declară o
variabilă memoria este alocată pentru a putea stoca valoare ei. Motorul colectării de
informaţie inutilă observă cu ce scop este folosită variabila de către program. Când programul
nu mai foloseşte variabila este ştearsă.
De exemplu avem următoarea secvenţă :
for (int x; x < 10; ++x)
System.out.println(x);
Întregul pe care îl folosim să număram până la 10 este de fapt declarat în interiorul buclei .
După ce bucla se termină spaţiul de memorie a variabilei x este curăţat şi se poate folosi de
câtre altcineva. Aceasta idee funcţionează la toate nivelele din cadrul mediului Java.
Securitatea
Excepţiile
6
Excepţiile nu sunt chiar noi – sunt folosite în C++. Oricum folosirea lor este dificilă în C++.
În java excepţiile sunt mult folosite. Excepţiile sunt condiţii de eroare care nu sunt aşteptate
de lungul cursului unei rulări standard a programului. Situaţii ca lipsa unui fişier va rezulta în
excepţii în Java. În Java, excepţiile sunt de fapt parte a limbajului; ele au clasele lor , interfeţe
, etc. În C++ excepţiile au fost o adăugare (add-on) care nu a fost niciodată pe deplin
implementată.
În C++ şirurile sunt simple tablouri de caractere . În Java şirurile pot fi mânuite ca şiruri . Nu
sunt tipuri primitive de date dar este de fapt o clasă şi deci şirul este instanţiat ca un obiect.
Dece atunci când se mânuiesc şirurile de fapt se manevrează cu un obiect String care are
propriile metode. În loc să se apeleze metodele care acţionează asupra şirului (C++) . de fapt
sunt apelate metodele obiectului şir care acţionează asupra lui. Dacă se doreşte se poate folosi
un tablou de caractere ca un şir dar se va pierde facilităţile uşor de folosit construite n clasa
String.
Clasa Super
Daca a-ţi folosit C++ sunteţi familiari cu cuvântul chei this care este folosit pentru a face
referire la obiectul curent. Java implementează de asemenea operatorul this , dar mai adaugă
şi operatorul super, care ii spune la Java să găsească clasa care este extinsă de clasa noastră
curentă . Se poate folosi super pentru a face un apel explicit la superclasa clasei curente.
Modificatori noi
În C++ modificatorii sunt folosiţi foarte frecvent. Java prei mulţi din modificatorii
C++ şi adaugă alţii noi. Mulţi dintre noii modificatori sunt pentru a ajuta în problemele de
securitate.
Câţiva dintre modificatorii noi :
abstract - folosiţi pentru a definii clase şi metode care trebuie sa fie moştenite (subclasate)
syncronized – spune la Java că o metodă poate fi apelată de un obiect pe rând.
native – folosit pentru a crea apeluri câtre limbaje ca C
final – spune la Java că o clasă nu pot fi moştenită .
Operatorul instanceof
Operatorul instanceof este foarte folositor atunci când ai de-a face cu obiecte şi nu eşti sigur
de tipul lor.
7
Capitolul 1. Elementele de bază ale limbajului Java
În această parte se vor evidenţia conceptele fundamentale despre elementele
fundamentale de programare în Java.
Comentarii
Identificatori
Cuvinte cheie
Declaraţii de variabile
1.1 Comentariile
Comentariile sunt utile deoarece contribuie la realizarea uni program uşor de intreţinut,
modificat şi folosit. Dar adăugarea de comentarii unei aplicaţii după ce este gata nu este o
bună practică. Mai des decât se crede , după o perioadă de timp departe de program nu iţi vei
aminti ce face acel cod pe care chiar tu l- ai scris . Din nefericire mulţi programatori urmează
această tradiţie. De aceea se sugerează să se scrie comentarii în timp ce se realizează
programul.
Java suportă 3 tipuri de stiluri de comentarii. Primele două sunt preluate din C++. AL
treilea tip de comentariu este folosit pentru a crea automat clase şi metode de documentaţie.
Acest stil de comentariu este folosit atunci când este nevoie de explicaţii pe mai multe linii .
Pentru a realiza acest lucru este nevoie de următorul set de simboluri /* şi */.
Exemplu :
/*
Acest program este scris de Vasi
Este cel mai deosibit program scris !
*/
while (i <= /* comentariul poate sa fie aici */ 10)
{
total += i;
i++;
}
// aici comentariu
Acest tip de comentariu este terminat de sfârşitul liniei, nu se pot folosi linii multiple
doar dacă fiecare linie începe cu un dublu slash (/)
Exemplu :
// Acest program este scris de Vasi
// Este cel mai deosibit program scris !
while (i <= 10) // comentariu aici
{
8
total += i;
i++;
}
Stilul de comentariu numarul 2
/** comentariu documentaţie aici... */
Acest stil de comentariu este asemănător cu cel de la stilul 1 cu excepţia uni asterisc în
plus la început. Compilatorul Java ignoră şi acest tip de comentariu dar un program denumit
JAVADOC:EXE care vine odată cu pachetul Java Development Kit foloseşte aceste
comentarii pentru a construi documentaţie HTML care descriu funcţiile , clasele şi pachetele .
Exemplu
/**
* Welcome to HelloWorld
* @author Anthony Potts
* @version 1.1
* @see java.lang.System
*/
class helloworld {
/**
* Main method of helloworld
*/
public static void main(String args[]) {
System.out.println("Hello World!");
}
}
1.2 Identificatori
9
1.3 Cuvinte cheie
În Java există cuvinte cheie care sunt rezervate şi alcătuiesc vocabularul limbajului. . Aceste
cuvinte nu pot fi folosite ca nume de identificatori pentru clase, variabile, pachete etc.
Tabelul 1.1. conţine lista completă a cuvintelor cheie din Java
10
private Modificator pentru clase, metode şi variabile
protected Modificator pentru clase, metode şi variabile
Public Modificator pentru clase, metode şi variabile
Return Folosit pentru a seta valoare returnată pentru o metoda
short Tipul de date intreg (16-bit values)
static Modificator pentru clase, metode şi variabile
super Folosit pentru a face referire la clasa parinte
Switch Instrucţiune folosite pentru a alege dintr-o listă de opţiuni
synchronized Modificator pentru o metodă care arată că acea metodă
poate fi executată o singur dată la un moment dat
Împiedică mediul Java să apeleze metoda a doua oară
până când prima nu s-a terminat.
this Folosit pentru a indica (a referi ) obiectul curent
throw Instrucţiune care arată mediului Java ce excepţie să
apeleze în cazul unei erori
transient Modificator care accesează cod Java nou
try Operator folosit pentru a testa excepţii n cod
void Modificator folosit pentru a desemna metodele fără tip de
date pentru revenire.
volatile Modificator de variabilă
while Folosit pentru a crea o structură repetitiva while
1.4 Literalii
Simbolurile literale sunt valori care sunt atribuite atunci când se introduc valori explicite . De
exemplu la o atribuire ca aceasta :
i = 10;
Aceste simboluri sunt de trei tipuri: numerice , caractere, boolean. Simbolurile boolean sunt
doar True şi False.
Literali numerici
Numerele pot fi întregi sau reale în virgulă mobilă. Numerele întregi sunt reprezentate de
obicei în format zecimal dar se pot introduce şi numere în format hexazecimal. . Pentru a
putea introduce un număr hexazecimal trebuie să înceapă cu simbolul 0x sai 0X. Numerele
întregi sunt stocate diferit în funcţie de mărimea lor. Tipul int este folosit pentru stocarea a
numere întregi pe 32 de biţi cu valori între -2,147,483,648 şi 2,147,483,648. Dacă se doreşte
folosirea de numere mai mari există în Java tipul long care stochează valori pe 64 de biţi în
domeniul
- 9.223372036855e+18 la 9.223372036855e+18.
Pentru a specific ca un număr este de tipul long se adaugă la sfârşitul numărului litera “l” sau
“L”
11
Se dau câteva exemple cum se pot folosi simbolurile literale intregi pentru a atribui valori
instrucţiunilor Java :
int i;
i = 1;
i= -9;
i = 1203131;
long lg;
lg = -9e15;
lg = 7e12;
Alt tip de simboluri literale numerice sunt numerele reale în virgulă mobilă. La fel ca şi
numerele întregi , valorile reale sunt reprezentate pe 32 de biţi şi 4 de biţi .
Exemple :
float f;
double d;
d = 1.0D; // valoare stocată pe 65 de biti -
d = -9.3645e235;
d = 7.0001e52D;
Literali caractere
Al doilea tip de literali de care este nevoie sunt literalii caractere. Literalii caractere includ
caractere individuale si şiruri.
Caracterele individuale sunt delimitate de apostrof în timp ce şirurile de caractere sunt
delimitate de ghilimele . Caracterele individuale pot fi orice caracter din setul de caractere
Unicode. De asemenea mai exisă câteva combinaţii speciale de două caractere care nu se
afişează dar au un rol important. Tabelul 1.2. arată aceste combinaţii speciale . Aceste
combinaţii sunt valabile şi pentru şiruri
12
\b BS Backspace
\r CR Carriage Return
\t HT Horizontal Tab
\\ \ Backslash
\’ ‘ apostrof
\” “ ghilimele
\xdd 0xdd Numar hexa
\ddd 0ddd Numar octal
\uddd 0xdddd Caracter Unicode
Exemple :
char ch;
ch = 'a';
ch = \n;
ch = \';
ch = \x30;
String str;
str = "Java string";
1.5 Operatori
Operatorii sunt folosiţi pentru a realiza calcule cu una sau mai multe variabile sau obiecte.
Operatori sunt folosiţi pentru a aduna variabile , compararea a două numere, atribuirea valori
unei variabile, incrementarea valori unei variabile, etc.
Tabelul 1.3. arată operatori folosiţi în Java .
13
^ SAU Exclusiv pe bit
| SAU pe bit
~ Complement pe bit
<< Deplasare stanga
>> Deplasare dreapta
>>> Deplasare dreapta si inlocuieşte cifrele deplasate cu zero
= Atribuire
+= Atribuire cu adunare
-= Atribuire cu scadere
*= Atribuire cu înmulţire
/= Atribuire cu împărţire
%= Atribuire cu rest
&= Atribuire cu SI pe bit
|= Atribuire cu SAU pe bit
^= Atribuire cu SAU Exclusiv pe bit
<<= Atribuire cu deplasare stanga
>>= Atribuire cu deplasare dreapta
>>>= Atribuire cu deplasare dreapta si inlocuite cifrele deplasate cu zero
1.6 Separatori
Separatorii în Java sunt foloiţo pentru a delimit blocuri de cod. De e4xmplu acoladele
sunt folosite pentru a delimita implemntarea unei metode. Şi se utilizează parantezele pentru
a cuprinde lista de parametrii a unei metode.
Variabilele sunt elemente care conţin informaţie în timp ce tipurile de date descriu ce
tip de informaţie este conţinut în element.
O variabilă trebuie să aibă un tip şi un identificator. Tipurile de date sunt byte, short,
int, long, float, şi double— apoi char şi boolean. Mai există şi tipul string care este de fapt
o clasă nu un tip de date.
14
Byte
Tipul byte poate fi folosit de variabilele care au nevoie de valori între-256 şi 255. Tipul byte
are lungimea de 8 biţi. Exemple de valori de tipul byte : -7 5 238
short
Tipul numeric short poate să stocheze valori între -32768 şi 32767. Are lungimea de 16 biţi.
Câteva exemple de valori : -7 256 -29524
int
Tipul de date int foloseşte valori întregi cu semn pe 32 de biţi cu valori maxime şi minime de
până la 2 miliarde. Având această plajă de valori este cel mai folosit tip de date pentru întregi.
De obicei , acest tip se foloseşte abuziv chiar dacă programul nu are nevoie de întreaga
rezoluţie a tipului. Dacă se folosesc numere întregi mici este indicat să se folosească tipul de
date short . Regula de bază ar fi dacă se cunoaşte exact domeniul de valori a unei variabile se
va folosi cel mai mic tip de date posibil. Aceasta va permite programului să folosească mai
puţină memorie şi astfel va rula mai rapid, în special la maşinile cu RAM limitat. Câteva
exemple de valori de tip int : -7 256 -29523234 1321412422
long
Tipul de date log este cel mai puternic tip de date întreg. Foloseşte 64 de biţi de informaţie
pentru a stoca valori ajungând până la 9 milioane de trilioane. Dacă se începe să se utilizeze
multe asemenea variabile , sau doamne fereşte un tablou de tip long , se poate consuma o tonă
de resurse. Câteva exemple de valori long : -7 256 -29523234 1.835412e15 -3e18
float
Tipul float este unul din cele două tipuri de date folosite pentru a stoca valori în virgulă
mobilă.
Tipurile în virgulă mobilă din Java pot stoca numere gigantice.
Exemple
-7F 256.0 -23e34 23e100
double
Ca şi cum tipul float nu ar conţine destule valori , tipul double suportă un spaţiu de stocare şi
mai mare. Definiţia SUN a valorilor posibile pentru un double : “Valoarea finită diferită de
zero de tipul double este de forma s * m * 2e, unde s este +1 sau -1, m este un întreg pozitiv
15
mai mic decât 2^53 şi e este un întreg între -1045 şi 1000 inclusiv ”. Din nou, avem aici
numere cu adevărat monstruoase . Dar atunci când ai dea face cu programarea dură , acest tip
de date devine necesar din când în când, deci este necesar să îi înţelegem domeniul. Aici
avem câteva exemple :
boolean
Tipul boolean are propriile lui valori True şi False, şi nu corespund altor valori. Java nu
permite conversie între tipul boolean şi ale tipuri. Această limitare nu este absolută, există
metode de conversie pentru a elimina acest neajuns.
char
Tipul char este folosit pentru a stoca caractere individuale. Deoarece Java foloseşte setul de
caractere Unicode, tipul caracter trebuie să fie capabil să stocheze mii de caractere, de aceea
se folosesc întregi pe 16 biţi cu semn. Tipul caracter are posibilitatea să fie convertit la
aproape toate tipurile.
string
Tipul şir este de fapt o clasă de sine stătătoare şi nu este un tip primitiv de date. N acest fel
şirurile nu sunt limitate ele pot să se modifice în timpul programului acest lucru realizându-se
în interiorul clasei şi nu ne interesează cum este implementat.
int i;
16
Unul din neajunsurile la modul cum implementează Java tablourile este acela că există
doar tablouri de o singură dimensiune. Pentru a folosi tablouri cu mai multe dimensiuni este
nevoie să se creeze tablouri de tablouri. Acest lucru se realizează însă uşor şi lipsa suportului
pentru tablouri multidimensionale nu ar trebuie sa ne împiedice cu nimic.
int[] intArray;
String[] Names;
Există trei tipuri pentru a seta dimensiunea unui tablou. Două dintre ele folosesc operatorul
new. Folosirea operatorului new va iniţializa toate elementele tabloului la o valoare implicită.
A treia metodă implică umplerea elementelor tabloului cu valori în timp ce este declarat
tabloul.
Prima metodă implică preluarea uni variabile declarate anterior şi setarea dimensiunii
tabloului . Aici avem câteva exemple :
Acum că şti, cum să iniţializăm tabloul , avem nevoie să învăţăm cum să umplem tabloul cu
date şi să accesăm elementele tabloului pentru a obţine date. Am arătat o modalitate foarte
simplă de a adăuga date la tablou când l-am iniţializat , dar de obicei aceasta nu este îndeajuns
de flexibilă pentru sarcini din lumea reală. Pentru a accesa o valoare a unui tablou trebuie să
cunoaştem poziţia acestuia. Sistemul de indexare folosit pentru a accesa elementele
tablourilor începe de la zero , ceea ce înseamnă că prim valoare este întotdeauna pe poziţia 0.
Să ne uităm la un mic program care prima data umple un tablou cu valori şi apoi le afişează.
17
public class powersOf2 {
Foarte simplu . Dacă se încearcă şi se foloseşte un index care depăşeşte limita tabloului , va
apărea o eroare la execuţie.
Tablourile multidimensionale sunt create în Java folosind tablouri de tablouri.. aici avem
câteva exemple de cum putem implementa tablourile multidimensionale .
int intArray[][];
String Names[][];
Putem să facem aceleaşi lucruri care le-am făcut şi cu tablourile cu o singură dimensiune.
Putem să realizăm tablouri care nu sunt neapărat dreptunghiulare. Adică fiecare tablou din
tabloul principal poate să aibă un număr diferit de elemente
18
Accesul datelor într-un tablou multidimensional nu este foarte mult diferit de accesul datelor
unui tablou cu o dimensiune .
Copierea vectorilor
Copierea unui vector în alt vector se face cu ajutorul metodei System.arraycopy:
Capitolul 2
19
class FirstApp {
public static void main( String args[]) {
System.out.println("Hello world");
}
}
C:/java/FirstApp.java
3. Compilarea aplicatiei
4. Rularea aplicatiei
java FirstApp
Rularea unei aplicatii care nu foloseate interfata grafica, se va face într-o fereastra sistem.
import java.awt.* ;
import java.applet.* ;
public class FirstApplet extends Applet {
Image img;
public void init() {
img = getImage(getCodeBase(), "taz.gif");
}
public void paint (Graphics g) {
g.drawImage(img, 0, 0, this);
20
g.drawOval(100,0,150,50);
g.drawString("Hello! My name is Taz!", 110, 25);
}
}
2. Compilarea applet-ului
Rularea applet-ului
Applet-urile nu ruleaza independent. Ele pot fi rulate doar prin intermediul unui
browser : Internet Explorer, Netscape sau printr-un program special cum ar fi
appletviewer-ul din setul JDK.
<html>
<head>
<title>First Java Applet</title>
</head>
<body>
<applet code=FirstApplet.class width=400
height=400>
</applet>
</body>
</html>
2. Vizualizarea appletului
appletviewer exemplu.html
Capitolul 3
21
1. Instructiuni de decizie
if-else, switch-case
2. Instructiuni de salt
for, while, do-while
3. Instructiuni pt. tratarea exceptiilor
try-catch-finally, throw
4. Alte instructiuni
break, continue, label: , return
a) if-else
if (exp_booleana)
{ /*...*/}
if (exp_booleana)
{ /*...*/}
else
{ /*...*/}
b) switch-case
switch (variabila) {
case val1 : /* ... */ break;
case val2 : /* ... */ break;
/*...*/
default : /*...*/
}
a) for
b)while
while (exp_booleana) {
/*...*/
}
c)do-while
22
do {
/*...*/
}while (exp_booleana) ;
return [valoare];
Atentie: In Java nu exista goto. Se pot însa defini etichete de forma nume_eticheta:, folosite
în expresii de genul: break nume_eticheta sau continue nume_eticheta
Exemplu:
i=0;
eticheta:
while (i<10) {
System.out.println("i="+i);
j=0;
while (j<10) {
j++;
if (j==5) continue eticheta;
if (j==7) break eticheta;
System.out.println("j="+j);
}
i++;
}
23
declarat cu StringBuffer. (vezi "Clasele String, StringBuffer") Exemple echivalente de
declarare a unui sir:
Concatenarea sirurilor
Concatenarea sirurilor de caractere se face prin intermediul operatorului +.
Atentie: Programele care folosesc argumente de la linia de comanda nu sunt 100% pure Java
deoarece unele sisteme de operare cum ar fi Mac OS nu au în mod normal linie de comanda.
Argumentele de la linia de comanda sunt introduse la lansarea unei aplicatii, fiind specificate
dupa numele aplicatiei si separate prin spatiu. De exemplu, sa presupunem ca aplicatia Sort
ordoneaza lexicografic liniile unui fisier si primeste ca argument numele fisierului pe care sa
îl sorteze. Pentru a ordona fisierul "persoane.txt" lansarea aplicatiei se va face astfel:
java Sort persoane.txt
Asadar, formatul general pentru lansarea unei aplicatii care primeste argumente de la linia de
comanda este:
java NumeAplicatie [arg1 arg2 . . . argn]
In cazul în care sunt mai multe, argumentele trebuie separate prin spatii iar daca unul dintre
argumente contine spatii, atunci el trebuie pus între ghilimele. Evident, o aplicatie poate sa nu
primeasca nici un argument sau poate sa ignore argumentele primite de la linia de comanda.
In momentul lansarii unei aplicatii interpretorul parcurge linia de comanda cu care a fost
lansata aplicatia si, în cazul în care exista, transmite aplicatiei argumentele specificate sub
forma unui vector de siruri. Acesta este primit de aplicatie ca parametru al metodei main.
Reamintim ca formatul metodei main din clasa principala este:
public static void main ( String args[])
Vectorul primit ca parametru de metoda main va contine toate argumentele transmise
programului de la linia de comanda. In cazul apelului java Sort persoane.txt vectorul
args va contine un singur element args[0]="persoane.txt".
Numarul argumentelor primite de un program este dat deci de dimensiunea vectorului args si
acesta poate fi aflat prin intermediul atributului length al vectorilor:
numarArgumente = args.length ;
Spre deosebire ce C/C++ vectorul primit de metoda main nu contine pe prima pozitie numele
aplicatiei, întrucât în Java numele aplicatiei este numele clasei principale, adica a clasei în
care se gaseste metoda main.
Exemplu: afisarea argumentelor primite la linia de comanda
24
public class Echo {
public static void main (String[] args) {
for (int i = 0; i < args.length; i++)
System.out.println(args[i]);
}
}
Un apel de genul java Echo Drink Hot Java va produce urmatorul rezultat:
Drink
Hot
Java
(aplicatia Echo a primit 3 argumente).
Una apel de genul java Echo "Drink Hot Java" va produce urmatorul rezultat:
Drink Hot Java
(aplicatia Echo a primit un singur argument).
Capitolul 4
Obiecte si clase in Java
25
1. Declararea obiectului
NumeClasa numeObiect;
Ex: Rectangle patrat;
2. Instantierea
Se realizeaza prin intermediul operatorului new si are ca efect crearea efectiva a
obiectului cu alocarea spatiului de memorie corespunzator.
3. Initializarea
Se realizeaza prin intermediul constructorilor clasei respective. Rectangle() este un
apel catre constructorul clasei Rectangle care este responsabil cu initializarea
obiectului. Initializarea se poate face si cu anumiti parametri, cu conditia sa existe un
constructor al clasei respective care sa accepte parametrii respectivi;
Fiecare clasa are un set de constructori care se ocupa cu initializare obiectelor nou create.
De exemplu clasa Rectangle are urmatorii constructori:
public Rectangle(Point p)
public Rectangle(int w, int h)
public Rectangle(Point p, int w, int h)
public Rectangle()
Declararea, instantierea si initializarea obiectului pot aparea pe aceesi linie (cazul cel mai
uzual):
Rectangle patrat = new Rectangle(0, 0, 100, 200);
Este posibila si crearea unor obiecte anonime care servesc doar pentru initializarea altor
obiecte, caz în care etapa de declarare a obiectului nu mai este prezenta:
patrat.origin = new Point(0, 0);
//se creeaza un obiect anonim de tip Point care,
//dupa executarea atribuirii este automat distrus de catre sistem
Atentie
Spatiul de memorie nu este pre-alocat
Declararea unui obiect nu implica alocarea de spatiu de memorie pentru acel obiect.
Rectangle patrat;
patrat.x = 10; //EROARE!
Alocarea memoriei se face doar la apelul instructiunii new !
26
patrat.x = 10;
patrat.y = 20; //schimba originea
patrat.origin = new Point(10, 20); //schimba originea
Obs: Accesul la variabilele unui obiect se face în conformitate cu drepturile de acces pe care
le ofera variabilele respective celorlalte clase. Apelul unei metode se face prin
obiect.metoda([parametri])
Rectangle patrat = new Rectangle(0, 0, 100, 200);
patrat.setLocation(10, 20); //schimba originea
patrat.setSize(200, 300); //schimba dimensiunea
Se observa ca valorile variabilelor pot fi modificate indirect prin intermediul metodelor.
Programarea orientata obiect descurajeaza folosirea directa a variabilelor unui obiect deoarece
acesta poate fi adus în stari inconsistente (ireale). In schimb, pentru fiecare variabila a
obiectului trebui sa existe metode care sa permita aflarea/schimbarea valorilor variabilelor
sale.
patrat.width = -100; //stare inconsistenta
patrat.setSize(-100, -200)
//metoda setSize poate sa testeze daca valorile sunt corecte si sa
//valideze sau nu schimbarea lor
• natural, atunci când variabila respectiva iese din domeniul sau, de exemplu la
terminarea unei metode
• explicit, daca atribuim variabilei respective valoare null.
Finalizare
Inainte ca un obiect sa fie eliminat din memorie, procesul gc da acelui obiect posibilitatea "sa
curete dupa el", apelând metoda de finalizare a obiectului respectiv. Uzual, în timpul
finalizarii un obiect îsi închide fisierele si socket-urile folosite, distruge referintele catre alte
obiecte (pentru a usura sarcina colectorului de gunoaie), etc. Codul pentru finalizare unui
obiect trebuie scris într-o metoda speciala numita finalize a clasei ce descrie obiectul
respectiv.
De exemplu, clasa Rectangle are urmatorul cod pentru finalizarea obiectelor sale:
class Rectangle {
27
...
protected void finalize() throws Throwable {
origin = null;
super.finalize();
}
}
Dupa numele clasei putem specifica, daca este cazul, faptul ca respectiva clasa este subclasa a
unei alte clase cu numele NumeSuperclasa sau/si ca implementeaza una sau mai multe
interfete, ale caror nume trebuie separate prin virgula.
Se observa ca, spre deosebire de C++, Java permite doar mostenirea simpla, asadar o clasa
28
poate avea un singur un singur parinte (superclasa). Evident o clasa poate avea oricâti
mostenitori (subclase). Extinderea unei clase se realizeaza deci astfel:
class B extends A {...} //A este superclasa clasei B
Spre deosebire de C++, nu este permisa doar declararea metodei în corpul clasei, urmând ca
implementare sa fie facuta în afara ei. Implementarea metodelor unei clase trebuie sa se faca
"inline" in corpul clasei.
In C++ In Java
class A { class A {
void metoda1(); void metoda(){
int metoda2() { //implementare
//implementare }
} }
}
A::metoda1() {
//implementare
}
Obs: variabilele unei clase pot avea acelasi nume cu metodele clasei.
29
Constructorii sunt apelati automat la instantierea unui obiect. In cazul în care dorim sa apelam
explicit constructorul unei clase folosim metoda this( argumente ), care apeleaza
constructorul corespunzator (ca argumente) al clasei respective. Aceasta metoda este folosita
atunci când sunt implementati mai multi constructori pentru o clasa pentru a nu repeta
secventele de cod scrise la constructorii cu mai putine argumente.
Dintr-o subclasa putem apela si constructorii superclasei cu metoda super( argumente ).
class Patrat extends Dreptunghi {
double size;
Patrat(double x0, double y0, double s0) {
super(x0, y0, s0, s0); //se apeleaza constructorul
superclasei
size = s0;
}
}
Constructorii sunt apelati automat la instantierea unui obiect.
In cazul în care scrieti o clasa care nu are declarat nici un constructor, sistemul îi creeaza
automat un constructor implicit care nu primeste nici un argument si care nu face nimic. Deci
prezenta constructorilor în corpul unei clase nu este obligatorie. Daca însa ati scris un
constructor pentru o clasa care are mai mult de un argument, atunci constructorul implicit
(fara nici un argument) nu va mai fi furnizat implicit de catre sistem.
class Dreptunghi {
//nici un constructor
}
...
Dreptunghi d;
d=new Dreptunghi(); -> OK (a fost generat constructorul implicit)
class Dreptunghi {
double x, y, w, h;
Dreptunghi(double x0, double y0, double wo, double h0) {
x=x0; y=y0; w=w0; h=h0;
}
}
...
Dreptunghi d;
d=new Dreptunghi(); -> Eroare la compilare
Constructorii unei clase pot avea urmatorii specificatori de acces:
30
4.2.4 Declararea variabilelor membre
Variabilele se declara de obicei înaintea metodelor, desi acest lucru nu este impus de
compilator.
class NumeClasa {
//declararea variabilelor
//declararea metodelor
}
Variabilele unei clase se declara în corpul clasei dar nu în corpul unei metode. Variabilele
declarate în cadrul unei metode sunt locale metodei respective.
Declararea unei variabile presupune specificarea urmatoarelor lucruri:
• numele variabilei
• tipul de date
• nivelul de acces la acea variabila de catre alte clase
• daca este constanta sau nu
• daca este variabila de instanta sau de clasa
Ex: double x;
protected static int n;
public String s = "abcd";
private Point p = new Point(10, 10);
final long MAX = 100000L;
31
transient Este folosit la serializarea obiectelor, pentru a specifica ce variabile membre
ale unui obiect nu participa la serializare (vezi "Serializarea obiectelor")
volatile Este folosit pentru a semnala compilatorului sa nu execute anumite
optimizari asupra membrilor unei clase. Este o facilitate avansata a
limbajului Java.
32
System.out.println("Eroare - numar negativ!");
//Eroare la compilare - lipseste return pe aceasta
ramura
}
In cazul în care în declaratia functiei tipul returnat este un tip primitiv de date, valoarea
returnata la terminarea functiei trebuie sa aiba obligatoriu acel tip, altfel va fi furnizata o
eroare la compilare.
Daca valoarea returnata este o referinta la un obiect al unei clase, atunci clasa obiectului
returnat rebuie sa coincida sau sa fie o subclasa a clasei specificate la declararea metodei. De
exemplu, fie clasa Poligon si subclasa acesteia Patrat.
Poligon metoda1( ) {
Poligon p = new Poligon();
Patrat t = new Patrat();
if (...)
return p; // legal
else
return t; // legal
}
Patrat metoda2( ) {
Poligon p = new Poligon();
Patrat t = new Patrat();
if (...)
return p; // ilegal
else
return t; // legal
}
Tipul de date al unui argument poate fi orice tip valid al limbajului, atât tip primitiv de date
cât si referinta la un obiect.
Ex: adaugarePersoana(String nume, int varsta, float salariu)
String este tip referinta, int si float sunt tipuri primitive
Spre deosebire de alte limbaje, în Java nu pot fi trimise ca parametri ai unei metode referinte
la alte metode (functii), însa pot fi trimise obiecte care sa contina implementarea acelor
metode, pentru a fi apelate. De asemenea, în Java o metoda nu poat primi un numar variabil
de argumente, ceea ce înseamna ca apelul unei metode trebuie sa se faca cu specificarea
exacta a numarului si tipurilor argumentelor.
Numele argumentelor primite trebuie sa difere între ele si nu trebuie sa coincida cu numele
nici uneia din variabilele locale ale metodei. Pot însa sa coincida cu numele variabilelor
membre ale clasei caz în care diferentierea se va face prin intermediul variabile this.
class Cerc {
int x, y, raza;
public Cerc(int x, int y, int raza) {
this.x = x;
this.y = y;
this.raza = raza;
}
}
Atentie: In Java argumentele sunt trimise doar prin valoare (pass-by-value)
Acest lucru însemna ca metoda receptioneaza doar valorile variabilelor primite ca parametri.
Când argumentul are tip primitiv de date metoda nu-i poate schimba valoarea decât local (în
cadrul metodei); la revenirea din metoda variabila are aceeasi valoare ca la apelul initial al
33
metodei (modificarile facute în cadrul metodei sunt pierdute).
Când argumentul este de tip referinta metoda nu poate schimba referinta obiectului însa poate
apela metodele acelui obiect si poate modifica orice variabila membra accesibila.
Asadar, daca dorim ca o metoda sa schimbe starea(valoarea) unui argument primit, atunci el
trebuie sa fie neaparat de tip referinta (trebuie sa fie un obiect!). De exemplu, sa consideram
clasa Cerc descrisa anterior si dorim sa implementam o metoda care sa returneze parametrii
cercului:
Varianta incorecta
...
int x = -1, y = -1, r = -1;
cerc.aflaParametri(x, y, r);
System.out.println("x = " + x + ", y = " + y + ", raza = " + r);
. . .
In acesct scop în clasa Cerc ar trebui sa avem o metoda de genul:
class Cerc {
int x, y, raza;
...
public void aflaParametri(int valx, int valy, int valr) {
//metoda nu functioneaza cum ar trebui!
valx = x;
valy = y;
valr = raza;
}
}
Aceasta metoda însa nu va realiza lucrul propul întrucât ea primeste doar valorile variabilelor
x, y si r adica (-1, -1, -1) si nu referinte la ele (adresele lor de memorie) astfel încât sa
le poata modifica valoarea. In concluzie, metoda nu realizeaza nimic pentru ca nu poate
schimba valorile unor variabile aflate în afara corpului ei.
Varianta corecta
Definim o clasa suplimentara care descrie parametrii pe care dorim sa-i aflam:
class CParam {
public int x, y, raza;
}
class Cerc {
int x, y, raza;
public void aflaParametri(CParam param) {
param.x = x;
param.y = y;
param.raza = raza;
}
}
...
CParam p = new CParam();
cerc.aflaParametri(p);
System.out.println("x = " + p.x + ", y = " + p.y + ", raza = " + p.raza);
34
• supraîncarcarea (overloading) : în cadrul unei clase pot exista metode cu acelasi
nume cu conditia ca signaturile lor sa fie diferite (lista de argumente primite sa difere
fie prin numarul argumentelor, fie prin tipul lor) astfel încât la apelul functiei cu acel
nume sa se poata stabili în mod unic care dintre ele se executa. Fenomenul de
supradefinire a metodelor se mai numeste si polimorfism.
• supradefinirea (overriding): o subclasa a unei clase poate rescrie o metoda a clasei
parinte, prin implementarea unei metode cu acelasi nume si aceeasi signatura ca ale
superclasei.
Exemplificare:
class A {
void metoda() {
System.out.println("A: metoda fara parametru");
}
//supraincarcare - polimorfism
void metoda(int arg) {
System.out.println("A: metoda cu un parametru");
}
}
class B extends A {
//supradefinire
void metoda() {
System.out.println("B: metoda fara parametru");
}
}
O metoda supradefinita poate sa:
• ignore complet codul metodei corespunzatoare din superclasa (cazul de mai sus)
• B b = new B();
• b.metoda(); -> afiseaza "B: metoda fara parametru"
• sa extinda codul metodei parinte, executând înainte de codul propriu si functia parinte.
•
• class B extends A {
• //supradefinire prin extensie
• void metoda() {
• super.metoda();
• System.out.println("B: metoda fara
parametru");
• }
• }
• . . .
• B b = new B();
• b.metoda(); -> afiseaza :
• "A: metoda fara parametru"
• "B: metoda fara parametru"
Metode finale
Specifica faptul ca acea metoda nu mai poate fi supradefinita în subclasele clasei în care ea
este definita ca fiind finala. Acest lucru este util daca respectiva metoda are o implementare
care nu trebuie schimbata sub nici o forma în subclasele ei, fiind critica pentru consistenta
35
starii unui obiect. De exemplu studentilor unei universitati trebuie sa li se calculeze media
finala în functie de notele obtinute la examene în aceeasi maniera, indiferent de facultatea la
care sunt.
class Student {
. . .
final float calcMedie(int nrExamene, float note[], float ponderi[])
{
...
}
. . .
}
class StudentInformatica extends Student{
float calcMedie(int nrExamene, float note[], float ponderi[]) {
return 10.00;
}
}//eroare la compilare!
Sunt cuvinte rezervate ce controleaza accesul celorlate clase la membrii unei clasei.
Specificatorii de acces pentru variabilele si metodele unei clase sunt: public, protected,
private si cel implicit (package), iar nivelul lor de acces este dat în tabelul de mai jos:
Specificator Clasa Subclasa Pachet Toti
private X
protected X X** X
public X X X X
package* X X
Exemple de declaratii:
private int secretPersonal;
proteceted String secretDeFamilie;
public Vector elemente;
long doarIntrePrieteni ; -> package
36
Variabile
Când declarati o variabila membra cum ar fi x în exemplul de mai jos:
class MyClass {
int x ; //variabila de instanta
}
se declara de fapt o variabila de instanta, cee ce însemna ca la fiecare creare a unei instante a
clasei MyClass sistemul aloca o zona de memorie separata pentru memorarea valorii lui x.
MyClass o1 = new MyClass();
o1.x = 100;
MyClass o2 = new MyClass();
o2.x = 200;
System.out.println(o1.x) -> afiseaza 100
System.out.println(o2.x) -> afiseaza 200
Asadar, fiecare obiect nou creat va putea memora valori diferite pentru variabilele sale de
instanta.
Pentru variabilele de clasa (statice) sistemul aloca o singura zona de memorie la care au acces
toate instantele clasei respective, ceea ce înseamna ca daca un obiect modifica valoarea unei
variabile statice ea se va modifica si pentru toate celelate obiecte.
class MyClass {
int x ; //variabila de instanta
static long n; //variabila de clasa
}
. . .
MyClass o1 = new MyClass();
MyClass o2 = new MyClass();
o1.n = 100;
System.out.println(o2.n) -> afiseaza 100
o2.n = 200;
System.out.println(o1.n) -> afiseaza 200
Metode
Similar ca la variabile, metodele declarate fara modificatorul static sunt metode de instanta
iar cele declarate cu static sunt metode de clasa (statice). Diferenta între cele doua metode
este urmatoarea:
• metodele de instanta opereaza atât pe variabilele de instanta cât si pe cele statice ale
clasei
• metodele de clasa opereaza doar pe variabilele statice ale clasei
• class MyClass {
• int x ; //variabila de instanta
• static long n; //variabila de clasa
• void metodaDeInstanta() {
• n ++; //legal
• x --; //legal
• static void metodaStatica() {
• n ++; //legal
• x --; //ilegal
• }
Intrucât metodele de clasa nu depind de starea obiectelor clasei respective, apelul lor se poate
face astfel:
MyClass.metodaStatica(); //legal, echivalent cu
MyClass obj = new MyClass();
obj.metodaStatica(); //legal
37
spre deosebire de metodele de instanta care nu pot fi apelate decât unei instante a clasei
respective:
MyClass.metodaDeInstanta(), //ilegal
MyClass obj = new MyClass();
obj.metodaDeInstanta(); //legal
1. Declararea constantelor
2. class MyClass {
3. final double PI = 3.14; //variabila finala de
instanta
4. }
class MyClass {
static final double PI = 3.14; //variabila finala de clasa
}
Folosind variabile statice putem controla diversi parametri legati de crearea obiectelor
unei clase
38
extrage radicalul unui numar si care se gaseste în clasa Math. Daca nu ar fi fost functie
de clasa, apelul ei ar fi trebuit facut astfel (incorect, de altfel):
13. Math obj = new Math();
14. double rad121 = obj.sqrt(121);
ceea ce ar fi fost extrem de neplacut pentru programatori. Fiind însa functie statica ea
poate fi apelata prin: Math.sqrt(121) .
class MyClass {
static final double PI = 3.14;
static long nrInstante = 0;
static final double EPS = 0.01;
}
class MyClass {
static {
final double PI = 3.14;
long nrInstante = 0;
final double EPS = 0.01;
}
}
class ClasaDeAcoperire{
. . .
class ClasaImbricata {
. . .
}
}
Folosirea claselor imbricate se face atunci când o alta clasa are nevoie în
implementarea ei de o alta clasa si nu exista nici un motiv pentru care clasa imbricata
sa fie declarata de sine statatoare (nu mai este folosita nicaieri).
39
class Destinatie { //clasa imbricata
private String dest;
private int termen;
Destinatie(String undePleaca, int inCateZile) {
dest = undePleaca;
termen = inCateZile;
}
}
Ca membra a unei clase, o clasa imbricata are un privilegiu special fata de celelalte
clase: acces nelimitat la variabilele clasei de acoperire, chiar daca acestea sunt private.
Clase interne
Ca orice alta clasa o clasa imbricata poate fi declarata statica sau nu. O clasa imbricata
nestatica se numeste clasa interna.
class ClasaDeAcoperire{
. . .
static class ClasaImbricataStatica {
. . .
}
class ClasaInterna {
. . .
}
}
o o "clasa imbricata" reflecta relatia sintactica a doua clase; codul unei clase
apare în interiorul dodului altei clase;
o o "clasa interna" reflecta relatia dintre instantele a doua clase, în sensul ca o
instanta a unei clase interne nu poate exista decât în cadrul unei instante a
clasei de acoperire.
40
Identificarea claselor imbricate
Dupa cum stim orice clasa produce la compilare asa numitele "unitati de compilare",
care sunt fisiere având numele clasei respective si extensia .class, si care contin toate
informatiile despre clasa respectiva.
Pentru clasele imbricate aceste unitati de compilare sunt denumite astfel: numele
clasei de acoperire, urmat de simbolul '$' apoi de numele clasei imbricate.
class ClasaDeAcoperire{
class ClasaInterna1 {}
class ClasaInterna2 {}
}
ClasaDeAcoperire.class
ClasaDeAcoperire$ClasaInterna1.class
ClasaDeAcoperire$ClasaInterna2.class
In cazul în care clasele imbricate au la rândul lor alte clase imbricate (situatie mai
putin uzuala) denumirea lor se face dupa aceeasi metoda : adaugarea unui '$' si apoi
numele clasei imbricate.
4.6 Clase si metode abstracte
Uneori în proiectarea unei aplicatii este necesar sa reprezentam cu ajutorul claselor
concepte abstracte care sa nu poata fi instantiate si care sa foloseasca doar la
dezvoltarea ulterioara a unor clase ce descriu obiecte concrete. De exemplu în pachetul
java.lang exista clasa abstracta Number care modeleaza conceptul generic de
"numar". Intr-un program nu avem însa nevoie de numere generice ci de numere
întregi, reale, etc. Clasa Number serveste ca superclasa pentru clase cum ar fi Byte,
Double, Float, Integer, Long si Short ce implementeaza obiecte pentru
descrierea numerelor de un anumit tip. Asadar clasa Number reprezinta un concept
abstract si nu vom putea instantia obiecte de acest tip:
Number numarGeneric = new Number(); //eroare
41
Metode abstracte
Spre deosebire de clasele obisnuite care trebuie sa furnizeze implementari pentru toate
metodele declarate o clasa abstracta poate contine metode fara nici o implementare.
Metodele fara nici o implementare se numesc metode abstracte si pot aparea doar în
clase abstracte.
In fata unei metode abstracte trebuie sa apara cuvântul cheie abstract, altfel va fi
furnizata o eroare de compilare.
In felul acesta o clasa abstracta poate pune la dispozitia subclaselor sale un model
complet pe care trebuie sa-l implementeze, furnizând chiar implementarea unor
metode comune tuturor claselor sau lasând explicitarea unor metode fiecarei subclase
în parte.
Un exemplu elocvent de folosire a claselor si metodelor abstracte este descrierea
obiectelor grafice într-o maniera orientata-obiect.
42
abstract class GraphicObject {
int x, y;
. . .
void moveTo(int newX, int newY) { //metoda normala
. . .
}
abstract void draw(); //metoda abstracta
} //nici
o implementare
Observatii:
O clasa abstracta poate sa nu aiba nici o metoda abstracta.
O metoda abstracta nu poate aparea decât într-o clasa abstracta.
Orice clasa care are o metoda abstracta trebuie declarata ca fiind abstracta.
4.7 Clasa Object
Dupa cum am vazut la crearea unei clase clauza "extends" specifica faptul ca acea
clasa este o subclasa a altei clase, numita superclasa. O clasa poate avea o singura
superclasa (Java nu suporta mostenirea multipla) si chiar daca nu specificati clauza
"extends" la crearea unei clase ea totusi va avea o superclasa. Cu alte cuvinte, in Java
orice clasa are o superclasa si numai una.
43
Superclasa tuturor celorlalte clase este clasa Object, care este radacina ierarhiei de
clase în Java. Clasa Object este si superclasa implicita a claselor care nu specifica o
alta superclasa. Declaratia class MyClass {} este echivalenta cu class MyClass
extends Object {}.
Clasa Object
Este cea mai generala dintre clase, orice obiect fiind, direct sau indirect, descendent al
acestei clase. Defineste si implementeaza comportamentul comun al tuturor claselor
Java cum ar fi:
Fiind sublcasa a lui Object, orice clasa poate supradefini metodele clasei Object care
nu sunt finale. Metode care pot fi supradefinite sunt: clone, equals/hashCode,
finalize ,toString
clone Acesasta metoda este folosita pentru duplicarea obiectelor (creearea unor clone).
Clonarea unui obiect presupune crearea unui nou obiect de acelasi tip si care sa
aiba aceeassi stare (aceleasi valori pentru variabilele sale)
equals, Aceste metode trebuie supradefinite împreuna. In metoda equals este scris
hashCode
codul pentru compararea a doua obiecte. Implicit (implementarea din clasa
Object) aceasta metoda compara referintele obiectelor. Uzual este redefinita
pentru a testa daca starile obiectelor coincid sau daca doar o parte din variabilele
lor coincid.
Metoda hashCode returneaza un cod întreg pentru fiecare obiect pentru a testa
consistenta obiectelor: acelasi obiect trebuie sa returneze acelasi cod pe durata
executiei programului. Daca doua obiecte sunt egale conform metodei equals
atunci apelul metodei hashCode pentru fiecare din cele doua obiecte trebuie sa
returneze acelasi întreg.
finalize In aceasta metoda se scrie codul care "curata dupa un obiect" înainte de a fi
eliminat din memorie de colectorul de gunoaie.
toString Este folosita pentru a returna o reprezentare ca sir de caractere a unui obiect.
44
Este utila pentru concatenarea sirurilor cu diverse obiecte în vederea tiparirii.
MyObject obj = new MyObject();
System.ot.println("Obiect=" + obj); //echivalent cu
System.ot.println("Obiect=" + obj.toString());
class OtherObject {
public int x;
//clasa in care NU este supradefinita metoda equals
}
o2 = o1;
if (o1.equals(o2))
System.out.println("test2: o1 == o2"); //corect
else
System.out.println("test2: o1 != o2");
//////////////////////////////////////////////
MyObject m1 = new MyObject();
MyObject m2 = new MyObject();
45
m1.x = 1;
m2.x = 1;
if (m1.equals(m2))
System.out.println("test3: m1 == m2"); //corect
else
System.out.println("test3: m1 != m2");
//x=1 pt ambele obiecte -> metoda equals returneaza true
MyObject m3;
m3 = (MyObject) m1.clone();
System.out.println("Obiectul clonat: " + m3); //echivalent
cu
System.out.println("Obiectul clonat: " + m3.toString());
//Se tipareste: Obiectul clonat: [1]
}
}
46
Capitolul 5
Interfete
47
Atentie
Variabilele unei interfete sunt implicit publice chiar daca nu sunt declarate cu
modificatorul public.
Variabilele unei interfete sunt implicit constante chiar daca nu sunt declarate cu
modificatorii static si final.
Metodele unei interfete sunt implicit publice chiar daca nu sunt declarate cu
modificatorul public.
In variantele mai vechi de Java era permis si modificatorul abstract în declaratia
interfetei si în declaratia metodelor, însa a fost eliminat deoarece atât interfata cât si
metodele sale sunt implicit abstracte.
interface Instrument {
//defineste o metoda fara implementare
void play();
}
48
public void play() {
System.out.println("Vioara.play()");
}
}
49
class NumeClasa implements Interfata1, Interfata2, ...
interface NumeInterfata extends Interfata1, Interfata2, ...
interface Inotator {
void inoata();
}
interface Zburator {
void zboara();
}
class Luptator {
public void lupta() {}
}
class Erou extends Luptator implements Inotator, Zburator {
public void inoata() {}
public void zboara() {}
}
interface Monstru {
void ameninta();
}
interface MonstruPericulos extends Monstru {
void distruge();
}
interface Mortal {
void omoara();
}
interface Vampir extends MonstruPericulos, Mortal {
void beaSange();
}
class Dracula implements Vampir {
public void ameninta() {}
public void distruge() {}
public void omoara();
public void beaSange() {}
}
Atentie
O clasa nu poate avea decât o superclasa
O clasa poate implementa oricâte interfete
O clasa mosteneste doar constantele unei interfete
O clasa nu poate mosteni implementari de metode dintr-o interfata
Ierarhia interfetelor este independenta de ierarhia claselor care le implementeaza
50
o definirea unor similaritati între clase independente fara a forta artificial o
legatura între ele.
o asigura ca toate clasele care implementeaza o interfata pun la dipozitie
metodele specificate în interfata; de aici rezulta posibilitatea implementarii
unitare a unor clase prin mai multe modalitati.
o specificarea metodelor unui obiect fara a deconspira implementarea lor (aceste
obiecte se numesc anonime si sunt folosite la livrarea unor pachete cu clase
catre alti programatori: acestia pot folosi clasele respective dar nu pot vedea
implementarile lor efective)
o definirea unor grupuri de constante
o transmiterea metodelor ca parametri (tehnica Call-Back) (vezi "Transmiterea
metodelor ca parametri").
interface functie {
public int executie(int arg);
}
class Graf {
//...
void explorare(functie f) {
//...
if explorarea a ajuns in nodul v
f.executie(v.valoare);
//...
51
}
}
Capitolul 6
Exceptii
52
Crearea unui obiect de tip exceptie se numeste aruncarea unei exceptii ("throwing an
exception"). In momentul în care o metoda genereaza o exceptie (arunca o exceptie) sistemul
de executie este responsabil cu gasirea unei secvente de cod dintr-o metoda care sa trateze
acea exceptie. Cautarea se face recursiv, începând cu metoda care a generat exceptia si
mergând înapoi pe linia apelurilor catre acea metoda.
Secventa de cod dintr-o metoda care trateaza o anumita exceptie se numeste analizor de
exceptie ("exception handler") iar interceptarea si tratarea exceptie se numeste prinderea
exceptiei ("catch the exception").
Cu alte cuvinte la aparitia unei erori este "aruncata" o exceptie iar cineva trebuie sa o "prinda"
pentru a o trata. Daca sistemul nu gaseste nici un analizor pentru o anumita exceptie atunci
programul Java se opreste cu un mesaj de eroare (în cazul exemplului de mai sus mesajul
"Aici nu se mai ajunge..." nu va fi tiparit).
Atentie: In Java tratarea erorilor nu mai este o optiune ci o constrângere. Orice cod care poate
provoca exceptii trebui sa specfice modalitatea de tratare a acestora.
Avantajele exceptiilor
Prin modalitatea sa de tratare a exceptiilor Java are urmatoarele avantaje fata de mecanismul
traditional de tratare a erorilor:
1. Separarea codului pentru tratarea unei erori de codul în care ea poate sa apara
2. Propagarea unei erori pâna la un analizor de exceptii corespunzator
3. Gruparea erorilor dupa tipul lor
53
aloca memorie;
if (s-a alocat memorie) {
citeste fisierul in memorie;
if (nu se poate citi din fisier) {
codEroare = -1;
}
} else {
codEroare = -2;
}
} else {
codEroare = -3;
}
inchide fisierul;
if (fisierul nu s-a inchis && codEroare == 0) {
codEroare = -4;
} else {
codEroare = codEroare & -4;
}
} else {
codEroare = -5;
}
return codEroare;
}//cod "spaghetti"
Acest stil de progamare este extrem de susceptibil la erori si îngreuneaza extrem de mult
întelegerea sa.
In Java, folosind mecansimul exceptiilor, codul ar arata astfel:
int citesteFisier {
try {
deschide fisierul;
determina dimensiunea fisierului;
aloca memorie;
citeste fisierul in memorie;
inchide fisierul;
}
catch (fisierul nu s-a deschis) {trateaza eroarea;}
catch (nu s-a determinat dimensiunea) {trateaza eroarea;}
catch (nu s-a alocat memorie) {trateaza eroarea }
catch (nu se poate citi dun fisier) {trateaza eroarea;}
catch (nu se poate inchide fisierul) {trateaza eroarea;}
}
54
int metoda1 {
int codEroare = apel metoda2;
if (codEroare != 0)
proceseazaEroare;
. . .
}
int metoda2 {
int codEroare = apel metoda3;
if (codEroare != 0)
return codEroare;
. . .
}
int metoda3 {
int codEroare = apel citesteFisier;
if (codEroare != 0)
return codEroare;
. . .
}
Java permite unei metode sa arunce exceptiile aparute în cadrul ei la un nivel superior, adica
functiilor care o apeleaza sau sistemului. Cu alte cuvinte o metoda poate sa nu îsi asume
responsabilitatea tratarii exceptiilor aparute în cadrul ei:
metoda1 {
try {
apel metoda2;
}
catch (exceptie) {
proceseazaEroare;
}
. . .
}
metoda2 throws exceptie{
apel metoda3;
. . .
}
metoda3 throws exceptie{
apel citesteFisier;
. . .
}
55
//exceptie specifica provocata de absenta fisierului
'input.dat'
} //sau
catch (IOException e) {
//exceptie generica provocata de o operatie de
intrare/iesire
} //sau
catch (Exception e) {
//cea mai generica exceptie - NERECOMANDATA!
}
56
FileInputStream sursa = null; //s este flux de intrare
int octet;
try {
sursa = new FileInputStream("fisier.txt");
octet = 0;
//citesc fisierul caracter cu caracter
while (octet != -1) {
octet = sursa.read();
System.out.print((char)octet);
}
catch (FileNotFoundException e) {
System.out.println("Fisierul nu a fost gasit !");
System.out.println("Exceptie: " + e.getMessage());
System.exit(1);
}
catch (IOException e) {
System.out.println("Eroare de intrare/iesire");
System.out.println("Exceptie: " + e.getMessage());
System.exit(2);
}
finally {
if (sursa != null) {
System.out.println("Inchidem fisierul...");
try {
sursa.close();
}
catch (IOException e) {
System.out.println("Fisierul poate fi
inchis!");
System.out.println("Exceptie: " +
e.getMessage());
System.exit(3);
}
}
}
}
57
Atentie: Obligatoriu un bloc de instructiuni "try" trebuie sa fie urmat de unul sau mai multe
blocuri "catch", în functie de exceptiile provocate de acele instructiuni sau (optional) de un
bloc "finally"
58
System.out.println("A aparut o exceptie);
throw e;
}
Aceasta instructune este folosita mai ales la aruncarea exceptiilor proprii care, evident, nu
sunt detectate de catre mediul de executie. (vezi "Crearea propriilor exceptii")
Clasa Error
Erorile (obiecte de tip Error) sunt cazuri speciale de exceptii generate de functionarea
anormala a echipamentului hard pe care ruleaza un program Java si sunt invizibile
programatorilor. Un program Java nu trebuie sa trateze aparitia acestor erori si este
improbabil ca o metoda Java sa provoace asemenea erori.
Clasa Exception
Obiectele de acest tip sunt exceptiile standard care trebuie tratate de catre programele Java. In
Java, tratarea exceptiilor nu este o optiune ci o constrângere.
Exceptiile care pot "scapa" netratate sunt încadrate în subclasa RuntimeException si se
numesc exceptii la executie.
In general metodele care pot fi apelate pentru un obiect exceptie sunt definite în clasa
Throwable si sunt publice, astfel încât pot fi apelate pentru orice tip de exceptie. Cele mai
uzuale sunt:
String getMessage( ) tipareste detaliul unei exceptii
void printStackTrace(
) tipareste informatii despre localizarea exceptiei
String toString( )
metoda din clasa Object, da reprezentarea ca sir de caractere a
exceptiei
59
In general tratarea exceptiilor este obligatorie în Java. De la acest principu se sustrag însa asa
numitele exceptii la executie sau, cu alte cuvinte, exceptiile care pot proveni strict din vina
programatorului si nu generate de o cauza externa.
Aceste exceptii au o superclasa comuna si anume RuntimeException si în acesata categorie
sunt incluse:
Aceste exceptii pot aparea uriunde în program si pot fi extrem de numeroare iar încercarea de
"prindere" a lor ar fi extrem de anevoioasa. Din acest motiv compilatorul permite ca aceste
exceptii sa ramâna netratate, tratarea lor nefiind însa ilegala.
int v[] = new int[10];
try {
v[10] = 0;
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Atentie la indecsi!");
e.printStackTrace();
}//legal
60
Fraza cheie este extends Exception care specifica faptul ca noua clasa MyEception este
subclasa a clasei Exception si deci implementeaza obiecte ce reprezinta exceptii.
In general codul adaugat claselor pentru exceptii proprii este nesemnificativ: unul sau doi
constructori care afiseaza un mesaj de eroare la iesirea standard.
Rularea programului de mai sus va produce urmatorul rezultat:
Exceptie in f()
MyException()
at TestMyException.f(TestMyException.java:12)
at TestMyException.main(TestMyException.java:20)
Exceptie in g()
MyException(): aruncata din g
at TestMyException.g(TestMyException.java:16)
at TestMyException.main(TestMyException.java:23)
Procesul de creare a unei noi exceptii poate fi dus mai departe prin adaugarea unor noi metode
clasei ce descrie acea exceptie, însa aceasta dezvoltare nu îsi are rostul în majoritatea
cazurilor. In general, exceptiile proprii sunt descrise de clase foarte simple chiar fara nici un
cod în ele, cum ar fi:
class SimpleException extends Exception { }
Aceasta clasa se bazeaza pe constructorul implicit creat de compilator însa nu are
constructorul SimpleException(String), care în practica nici nu este prea des folosit.
61
Capitolul 7
Pachete
62
numele pachetelor. Asadar numele complet al unei clase este format din numele pachetului la
care apartine + numele sau:
numePachet.NumeClasa
Ex: java.lang.String (java.lang=pachet, String=clasa)
De exemplu sa presupunem ca în aplicatia noastra folosim o clasa numita Stack:
package my_package;
class Stack { ... }
Clasa Stack exista deja în pachetul java.util. Diferentierea între cele doua clase se va face
prin specificarea numelui complet al clasei, adica numelePachetului.NumeleClasei:
java.util.Stack s1 = new java.util.Stack();
my_package.Stack s2 = new my_package.Stack();
Ce se întâmpla însa când doi programatori care lucreaza la un proiect comun folosesc clase cu
acelasi nume ce se gasesc în pachete cu acelasi nume ? Pentru a evita acest lucru companiile
folosesc inversul domeniului lor Internet în denumirea pachetelor implementate în cadrul
companiei, cum ar fi com.company.numePachet. In cadrul unei aceeasi companii conflictele
de nume trebuie rezolvate prin diverse conventii de uz intern.De exemplu, adresa mea de e-
mail este acf@infoiasi.ro, ceea ce înseamna ca domeniul meu Internet este infoiasi.ro.
Pachetele create de mine ar trebui denumite ro.infoiasi.NumePachet. Pentru a rezolva
conflicte cu alti programatori din acelasi domeniu cu mine pachetele s-ar putea numi:
ro.infoiasi.acf.NumePachet.
Folosirea membrilor unui pachet
Conform specificatiilor de acces ale unei clase si ale membrilor ei doar clasele publice si
membrii declarati publici ai unei clase sunt accesibili în afara pachetului în care acestea se
gasesc.
Pentru a folosi o clasa publica dintr-un pachet sau pentru a apela o metoda publica a unei
clase public a unui pachet exista trei solutii:
Specificarea numelui complet al calsei se face, asa cum am vazut, prin prefixarea numelui
clasei cu numele pachetului: numePachet.NumeClasa. Aceasta metoda este recomandata doar
pentru cazul în care folosirea acelei clase se face o singura data sau foarte rar. De exemplu ar
fi extrem de neplacut sa scriem de fiecare data când vrem sa declaram un sir de caractere sau
sa folosim un obiect grafic secvete de genul;
java.lang.String s = "neplacut";
java.awt.Rectangle r = new java.awt.Rectangle();
java.awt.Circle c = new java.awt.Circle();
In aceste situatii vom importa (include) clasa respective sau întreg pachet din care face parte
in aplicatia noastra. Acest lucru se realizeaza prin instructiunea import, care trebuie sa apara
la începutul fisierelor sursa, imediat dupa instructiunea package.
Importul unei clase sau interfete
Se face printr-o instructiune import în care specificam numele clasei (interfetei) pe care dorim
sa o folosim dintr-un pachet:
import java.awt.Rectangle;
Din acest moment vom putea folosi în clasele fisierului în care am plasat instructiunea de
import numele scurt al clasei Rectangle
Rectangle r = new Rectangle(0,0,100,100);
63
Aceasta abordare este eficienta în cazul în care nu avem nevoie decât de acea clasa sau doar
de câteva clase din pachetul respectiv. Daca în exemplul nostru am avea nevoie si de clasele
Circle, Line, Point, Polygon ar trebui sa avem câte o instructiune de import pentru
fiecare dintre ele:
import java.awt.Rectangle;
import java.awt.Circle;
import java.awt.Line;
import java.awt.Point;
import java.awt.Polygon;
In aceasta situatie ar fi recomandat importul întregului pachet si nu al fiecarei clase în parte.
Se face printr-o instructiune import în care specificam numele pachetului ale carui clase si
interfete dorim sa le folosim dintr-un pachet, urmat de simbolul '*'. Se mai numeste import la
cerere deoarece încarcarea claselor se face dinamic în momentul apelarii lor. Este cel mai
uzual tip de import.
import java.awt.*;
Din acest moment vom putea folosi în clasele fisierului în care am plasat instructiunea de
import numele scurt al tuturor claselor pachetului importat:
Rectangle r = new Rectangle();
Circle c = new Circle(); ...
Atentie
* nu are semnificatia uzuala de wildcard (masca) si nu poate fi folosit decât ca atare.
import java.awt.C*; //eroare de compilare
In cazul în care sunt importate doua pachete care contin o clasa cu acelasi nume atunci
referirea la ea trebuie facuta folosind numele complet al clasei respective.
//Stack.java
package my_package;
class Stack { ... }
//alt fisier sursa
import java.util.*;
import my_package.*;
...
Stack s = new Stack(); //ilegal -> conflict de nume
java.util.Stack s1 = new java.util.Stack(); //corect
my_package.Stack s2 = new my_package.Stack();//corect
Mediul Java importa automat trei pachete pentru toate fisierele sursa:
• pachetul java.lang
• pachetul curent
• pachetul implicit (fara nume)
64
java.beans suport pentru scrierea de componente reutilizabile
java.io intrari/iesiri, acces la fisiere
java.lang clasele de baza ale limbajului
java.math operatii matematice
java.net acces la retea
java.rmi executie la distanta (Remote Message Interface)
java.security mecanisme de securitate : criptare, autentificare
java.sql interogari SQL
java.text suport pentru formatarea textelor
java.util clase utile : Vector, Stack, Random, etc
Pachetul java.lang contine elementele de baza ale limbajului si este importat automat.
65