Sunteți pe pagina 1din 17

Curs: Core Java Programming

Modul: Bazele programării Java


Unitate: Tipuri de date

Pentru a gestiona datele dintr-un limbaj de programare, trebuie să


cunoaştem tipurile de date susţinute de acest limbaj. Tipurile de date
diferă de la limbaj la limbaj, dar diferenţele sunt cel mai des doar
"cosmetice" (diferă numele lor) şi nu reale şi în general toate limbajele
au tipuri de date caracteristice cu, eventual, nişte nume diferite.

Ce este tipul de dată şi la ce foloseşte?

Deja am spus că unele date se prezintă în program prin nişte tipuri,


ceea ce permite programului să nu se "încurce" când trebuie să le
gestioneze. Dacă am întreba pe cineva câţi ani are şi dacă persoana
respectivă ne-ar răspunde : "Ion", probabil că ne-am încurca. Ar fi şi
mai rău dacă ar trebui să calculăm vârsta medie, dar înainte de asta
să fi obţinut informaţia schimbată referitoare la vârstă (Ion). În acest
caz, o simplă calculare a vârstei medii ar fi, practic, imposibilă.

Unele limbaje de programare (de nivel înalt) sunt capabile să trateze


singure această problemă (de exemplu, dacă expediem textul în locul
numărului, acesta este tratat ca numărul zero şi alte soluţii
asemănătoare), dar unele nu. Java cere tipuri explicit identificate, fapt
pentru care aparţine grupului de limbaje de programare Strongly
Typed. Aceasta înseamnă că, dacă în Java spunem că aşteptăm un
număr şi expediem textul, programul nu va fi tradus.

Să ne întoarcem la exemplul cu vârsta. Care este de fapt tipul de date


pe care îl aşteptăm după ce întrebăm interlocutorul câţi ani are? Este
evident că e vorba de un număr, dar acest număr poate fi întreg sau
zecimal. Interlocutorul ne poate răspunde 25 sau 25 şi jumătate. Dacă
ne-am aştepta să ne spună un număr întreg şi el ne spune un număr
zecimal, am pierde partea de după virgulă. De aceea, se poate spune
că cea mai sigură variantă este să presupunem că numărul aşteptat
va fi zecimal, pentru că atunci nu există posibilitatea să pierdem nicio
informaţie. Pe lângă tipul de număr, este foarte importantă şi mărimea
numărului gestionat. În creierul uman, alocarea memoriei se întâmplă
în mod dinamic, dar în programul de calculator nu. Odată ce am
ocupat un spaţiu în memorie unde intenţionăm să păstrăm un număr,

© Copyright Link group 1 / 17


Curs: Core Java Programming
Modul: Bazele programării Java
Unitate: Tipuri de date

acest spaţiu rămâne ocupat până la dealocarea sau oprirea


programului. Este foarte important cât de mare va fi acest spaţiu,
pentru că acesta afectează în mod direct memoria disponibilă a
mediului. Dacă vorbim de anii vieţii umane, ştim că nu există
posibilitatea ca cineva să trăiască mai mult de 150 de ani. De
asemenea, ştim că anii vieţii nu pot fi prezentaţi printr-o valoare
negativă. Deci, pentru memorarea vârstei umane este suficient cel
mai mic număr zecimal cu virgulă mobilă - Float.

Tipuri de date în Java

Practic toate limbajele de programare subînţeleg împărţirea generală a


tipurilor de date în simple (primitive) şi compuse. Această împărţire
este exprimată foarte clar la limbaje orientate către obiecte cum ar fi
Java, unde toate componentele limbajului, până şi tipurile însele, sunt,
de fapt, obiecte. Tipurile simple sunt tipurile care nu se pot
descompune în subcomponente. Aceste tipuri sunt stocate în partea
statică a memoriei (Stack), unde ocupă un spaţiu cu ocazia activării
programului. Tipurile compuse sunt, de obicei, compuse dintr-unul sau
mai multe tipuri simple, care au nişte caracteristici şi/sau
funcţionalităţi suplimentare. Astfel de tipuri se află de obicei în partea
dinamică a memoriei (Heap), în timp ce în partea statică se află doar
adresa care indică valoarea lor reală în memoria dinamică. Acest lucru
este logic pentru că dimensiunile acestori tipuri sunt adeseori flexibile.

Tipurile simple

Java cunoaşte următoarele tipuri primitive:

© Copyright Link group 2 / 17


Curs: Core Java Programming
Modul: Bazele programării Java
Unitate: Tipuri de date

Mărimile prezentate în lista de mai sus sunt obţinute simplu. Dacă ştim
că unui tip i se permite să ocupe o mărime de un octet, aceasta
înseamnă că e vorba de mărimea de 8 biţi. Opt biţi este, de fapt, 2 la
8, din care obţinem numărul 256, ceea ce reprezintă valoarea maximă
care încape în această gamă.

Tipurile menţionate sunt simple. Deci, nu se pot descompune în părţi


constitutive. De asemenea, aceste tipuri trebuie obligatoriu iniţializate
pentru a fi folosite. Aceasta este o regulă doar în anumite situaţii,
atunci când tipurilor li se atribuie valori subînţelese fără iniţializare. De
exemplu, când se iniţializează un tablou (şir) de tipuri simple. În orice
caz, practica bună este iniţializarea variabilelor, mai degrabă decât
folosirea valorilor lor subînţelese. Fireşte, aici vorbim despre cazuri în
care valorile subînţelese nu apar deloc (de exemplu, cazul iniţializării
şirului). Cel mai adesea, gestionarea variabilei cere iniţializarea ei fără
de care programul nici nu poate fi tradus.

Tipurile simple se declară prin numele tipului urmat de numele


variabilei:

int variabilaMea;

Această linie declară variabila variabilaMea de tip Int. Acest "program"


va fi interpretat fără nicio problemă, căci nu mutăm nicăieri variabila
variabilaMea. Însă, dacă am dori să facem orice cere participarea
acestei variabile, iar acest lucru să nu fie atribuirea valorii acestei
variabile, traducătorul ar semnala o greşeală.

© Copyright Link group 3 / 17


Curs: Core Java Programming
Modul: Bazele programării Java
Unitate: Tipuri de date

De exemplu:

int i;
System.out.println(i);

Acest cod induce o eroare pentru că încercăm să folosim o variabilă


neiniţializată x. Pentru a elimina eroarea, trebuie să iniţializăm această
valoare înainte de folosire.

int x=5;
System.out.println(x);

sau

int x;
x=5;
System.out.println(x);

După cum se poate vedea din ultimul exemplu, variabila nu trebuie


neapărat declarată şi iniţializată în acelaşi timp, dacă la final aceasta
este iniţializată.

Concret, o variabilă de tip Integer poate fi iniţializată prin trei sisteme


numerice: zecimal, octal şi hexazecimal. Notaţia zecimală se foloseşte
cel mai frecvent şi este implicită. Dacă scriem int x=5; traducătorul o
va înţelege ca iniţializarea valorii zecimale. Dacă dorim ca valoarea să
fie octală, adăugăm un zero în faţa numărului. De exemplu, dacă am
scrie int i=010; nu am obţine numărul zece, cum poate ne aşteptăm,
ci numărul 8, deoarece prin cifra zero îi aducem la cunoştinţă
traducătorului că vom reprezenta valoarea în mod octal. Dacă dorim
să introducem o valoare hexazecimală, punem marcajul 0x în faţa
numărului, astfel încât după linia int x=0xF; variabila x va purta
valoarea 15, deoarece în sistemul hexazecimal, acest număr este
reprezentat prin marcajul F.

Am menţionat că există şi cazuri în care variabila obţine o valoare


implicită pentru tipul ei. Valoarea implicită pentru tipul Int este 0 şi
atribuirea valorii iniţiale acestui tip se poate face prin crearea unui şir

© Copyright Link group 4 / 17


Curs: Core Java Programming
Modul: Bazele programării Java
Unitate: Tipuri de date

de Int-uri:

int[] i = new int[5];


System.out.println(i[1]);

Dacă activăm acest program, se va afişa valoarea 0, deşi nicăieri nu


am definit această valoare, ceea ce înseamnă că a fost folosită
valoarea implicită.

În acest moment, încă nu ştim precis ce sunt şirurile (tablourile) astfel


încât exemplul de faţă este puţin confuz, dar scopul lui este mai
degrabă să arate comportamentul specific al tipului, decât să prezinte
în orice fel tipurile despre care va fi vorba mult mai detaliat în lecţiile
ce urmează. De asemenea, şi despre iniţializare vom vorbi mai mult
atunci când va fi vorba despre operatori.

După principiul Int-ului funcţionează şi alte tipuri simple. Unica


diferenţă în ceea ce priveşte folosirea lor este limitarea valorică
prezentată în tabel.

De exemplu:

short x = 2147483648;

va semnala o eroare, căci acest tip nu este în stare să suporte o


valoare aşa de mare:

short x = 32767;

şi va fi în regulă.

Trebuie să avem grijă ca pentru valori numerice mari să folosim


adesea tipuri textuale, mai degrabă decât numerice. Astfel, de
exemplu, pentru codul numeric personal nu folosim niciodată tipul
Long, ci mai degrabă Char[] sau String.

Tipul boolean este prezentat în tabel ca tip de un bit, care poate purta
valoarea 1 sau 0. Valoarea acestui tip, totuşi, se reprezintă prin

© Copyright Link group 5 / 17


Curs: Core Java Programming
Modul: Bazele programării Java
Unitate: Tipuri de date

valorile true sau false (corect şi incorect) şi se foloseşte foarte frecvent


în cod, mai ales în controlul de flux. Adesea, şi chiar în mod
inconştient, la programare se gestionează tocmai acest tip pentru că
fiecare expresie verificată rezultă de obicei la sfârşit într-o valoare de
acest tip. Pentru a iniţializa o variabilă cu valoarea acestui tip, folosim
aceeaşi sintaxă ca şi pentru celelalte tipuri simple:

boolean x = true;

respectiv

boolean x = false;

Tipul Char se reprezintă puţin diferit. Acest tip poate fi iniţializat


printr-un caracter sau prin codul lui pentru că, de fapt, fiecare caracter
este reprezentat prin valoarea de doi octeţi. Astfel, următoarele două
iniţializări vor avea, de fapt, valoare complet identică şi ieşirea
programului următor va fi AA:

char myLetter = A;
byte myByte = 65;
System.out.print(myLetter);
System.out.print((char)myByte);

Şiruri

Pe de altă parte, vom menţiona imediat şirul, ca tip de date. Acesta


este, spre deosebire de tipurile pomenite anterior, un tip de date
complex. Această dată conţine, de fapt, mai multe date de acelaşi tip,
care se extind prin memorie într-o listă de mărime fixă. Când se
creează şirul, este necesar să-i menţionăm mărimea exactă, pentru ca
tabloul să se stocheze într-o parte alocată a memoriei. În momentul
iniţializării, pe anumita adresă de memorie se pune primul membru al
şirului, urmat de ceilalţi membri, ordonaţi secvenţial. Utilizatorul
(programator/program) obţine în momentul manipulării o variabilă în
care, de fapt, se află o adresă de memorie a membrului iniţial al şirului

© Copyright Link group 6 / 17


Curs: Core Java Programming
Modul: Bazele programării Java
Unitate: Tipuri de date

şi pe baza aceasta se manipulează şi toţi ceilalţi membri. Acest lucru


nu este aşa de greu, cum sună, căci în mod obişnuit ne adresăm
membrilor şirului prin indicele lor (desupra fiecărui membru se află un
indice) care merg de la 0 până la ultimul indice, care este mai mic cu
unu decât suma membrilor şirului. În exemplul următor avem
prezentat un şir de numere (5,2,8,4,1,3,3,7,1,0). Când programul
obţine variabila care reprezintă şirul, are adresa primului membru (5),
respectiv a indicelui său (0). Pe baza acestor date, este foarte simplu
să ajungă la ceilalţi membrii, prin apelarea indicelui corespunzător.
Astfel, dacă apelăm indicele 7 vom obţine valoarea 7, dacă apelăm
indicele 8 vom obţine valoarea 1, iar dacă apelăm indicele 3 vom
obţine valoarea 4. În aproape toate implementările, indicii subînţeleg
indexarea aşa-numită Zero Based, respectiv, primul membru al şirului
se află întotdeauna pe poziţia 0 (şi nu unu, cum ar fi logic, la prima
vedere).

Obiecte

Cel mai complex tip, în toate limbajele orientate către obiecte, este
desigur tipul obiect. Obiectul este ceva ce, deşi structural, poate fi
foarte simplu, poate fi şi extrem de complex şi depinde de imaginaţia,
respectiv, de necesităţile programatorului/programului.

Povestea despre obiecte şi programarea obiectivă este "fără sfărşit" şi


în orice caz prea complexă pentru noi în acest moment. Însă, modelul
obiectiv simbolizează Java şi, vrem sau nu vrem, nu putem învăţa
limbajul Java fără a cunoaşte foarte bine modelul obiectiv. Deja am
menţionat că în limbajul Java totul este obiect. De fapt... aproape totul.
Am menţionat tipurile simple, care nu sunt obiecte, dar în Java chiar şi
aceste tipuri se folosesc în mod obişnuit "împachetate" în obiecte,
pentru a li se adăuga funcţionalitate.

© Copyright Link group 7 / 17


Curs: Core Java Programming
Modul: Bazele programării Java
Unitate: Tipuri de date

În pasajele precedente am folosit cuvântul cheie Int pentru iniţializarea


tipului număr întreg. În acelaşi scop putem folosi acum cuvântul
(obiectul) cheie Integer.

Integer x=5;

În ambele cazuri, x va avea la final valoarea 5, deşi în fundal se va


desfăşura o logică complet diferită. În primul rând, la iniţializarea
Int-ului, valoarea variabilei se va stoca direct în partea statică a
memoriei, dar în cazul lui Integer, în partea statică se va stoca doar
adresa obiectului, obiectului care se va afla în partea dinamică a
memoriei (Heap). Spre deosebire de iniţializarea prin cuvântul cheie
Int, acum avem la dispoziţie şi un set de funcţionalităţi care se pot
executa asupra acestei variabile care, de fapt, nu mai este un tip
simplu ci un obiect.

Exemplul următor vă va arăta tipul exact al variabilei x:

Integer x=5;
System.out.println(x.getClass());

La introducerea marcajului . după valoarea x, dacă folosiţi mediul


NetBeans, apare lista funcţiilor disponibile şi a proprietăţilor obiectului
actual.

© Copyright Link group 8 / 17


Curs: Core Java Programming
Modul: Bazele programării Java
Unitate: Tipuri de date

Toate aceste elemente se pot aplica asupra obiectului actual.

De exemplu, putem compara obiectul actual cu un alt obiect sau


valoare:

Integer x=5;
System.out.println(x.equals(6));

Rezultatul acestui cod este valoarea falsă scrisă la ieşire (la fereastra
Output a NetBeans).

Evident că Integer este o structură de date complexă care conţine


multe caracteristici adiţionale, lipsite la Int însuşi. Putem spune liber
că, dacă am prezenta valoarea completă a tipului Integer, nu am
obţine doar valoarea 5, ci şi o mulţime de proprietăţi ale acestui
obiect. Pe de altă parte, Int are sub el doar valoarea 5 care este unica
reprezentare purtată de acest tip. De aceea un astfel de tip se
numeşte Literal.

Unul dintre tipurile des folosite în programare este tipul String. Acest

© Copyright Link group 9 / 17


Curs: Core Java Programming
Modul: Bazele programării Java
Unitate: Tipuri de date

tip, de fapt, nu există în Java ca tip simplu, ci doar ca obiect. Acest


lucru este logic, de fapt, pentru că String nu este nimic altceva decât o
secvenţă - un şir de caractere. Pe de altă parte, String-ul, în general,
este considerat (deşi nu este) un tip simplu şi ca atare aduce o
împărţire în tipuri simple, la: valorile textuale şi numerice.

String x = "Hello java";


System.out.println(x);

În Java, String are proprietatea Immutable. Aceasta înseamnă că,


odată creat nu se poate schimba. Această declaraţie poate părea
imposiblă, dar aşa este într-adevăr. Şi orice schimbare în String este,
de fapt, crearea unui nou obiect String. La ce trebuie acordată o
atenţie specială cu ocazia gestionării acestui tip?

Observăm că numele tipurilor obiective încep cu majuscule, iar numele


tipurilor simple încep cu litere minuscule. Aceasta este partea practicii
ca toate numele claselor să înceapă cu litere majuscule.

Până acum ştim că există tipuri simple, incluse în limbajul însuşi şi


tipuri compuse, construite din tipuri simple. Mai există un tip care se
foloseşte frecvent, dar despre care nu se poate spune că este simplu
sau compus (deşi, de fapt, este compus): tipul Null. Acest tip
reprezintă, de fapt, lipsa valorii şi prin el cel mai adesea putem să
identificăm dacă un obiect există sau nu există. Motivul pentru care
care am scris în paranteze că acest tip este de fapt compus, este că
Null se poate folosi doar cu obiecte, nu şi cu tipuri primitive. Astfel,
codul următor va fi tradus bine:

Integer x = null;

Dar codul urm?tor nu va fi tradus bine, ci va semnala o


eroare:

int x = null;

© Copyright Link group 10 / 17


Curs: Core Java Programming
Modul: Bazele programării Java
Unitate: Tipuri de date

Conversiile tipurilor

Când creăm o variabilă de un anumit tip, nu înseamnă că vom rămâne


veşnic în acest tip. Dimpotrivă, putem transforma o variabilă dintr-un
tip în altul foarte simplu. Bineînţeles, numai dacă există condiţii pentru
această transformare. De exemplu, dacă avem o valoare de tip text
(de exemplu "textul meu"), o astfel de valoare nu se poate converti în
număr pentru că nu conţine nimic care să reprezinte o valoare
numerică. Pe de altă parte, numărul zecimal 3.14 se poate converti
foarte simplu în valoare număr întreg, astfel încât să rotunjim partea
de după virgulă la valoarea dorită. Încă şi mai uşor este să
transformăm un număr întreg în număr zecimal, adăugând virgula
zecimală şi un zero după ea. Toate tipurile simple au, în reprezentarea
lor obiectivă şi metode pentru conversie.

De exemplu:

String piString = "3.14";


float pi = Float.parseFloat(piString);
System.out.println(pi);

În acest exemplu, la început, apare variabila de tip string (piString). În


a doua linie, se face conversia şi String-ul se transformă în tip Float,
pentru a fi emis la ieşire după aceea. Poate că această conversie nu
pare destul de importantă fiindcă putem emite numărul pi la ieşire şi
fără conversie, ca String. În acest caz, însă, dacă s-ar efectua orice
operaţie matematică în care participă variabila neconvertită, s-ar
produce o eroare.

Codul următor semnalează o eroare:

String piString = "3.14";


double r = 3;
double circleArea = piString * Math.pow(r, 2);
System.out.println(circleArea);

Dar acest cod va fi valabil:

© Copyright Link group 11 / 17


Curs: Core Java Programming
Modul: Bazele programării Java
Unitate: Tipuri de date

String piString = "3.14";


double r = 3;
double pi = Double.parseDouble(piString);
double circleArea = pi * Math.pow(r, 2);
System.out.println(circleArea);

Conversia se poate face şi prin paranteze rotunde. Această conversie


funcţionează doar în cadrul mărimilor diferite ale unei clase de tip. De
exemplu, doar în cadrul tipurilor de număr întreg sau în cadrul tipurilor
cu virgulă mobilă etc.

Exemplul următor nu va funcţiona. Logic, pentru că cerem tipului de


patru octeţi să accepte o valoare mai mare de patru octeţi.

short smallNumber = 1000;


num?rMic = smallNumber * 100;
System.out.println(num?rMic);

Corectat în felul următor, exemplul va funcţiona:

short smallNumber = 1000;


int bigNumber = (int) smallNumber * 100;
System.out.println(bigNumber);

Exemplul de mai sus poate funcţiona şi aşa:

short smallNumber = 1000;


int bigNumber = smallNumber * 100;
System.out.println(bigNumber);

În acest caz, traducătorul ar face singur conversia, ceea ce este


acceptabil pentru acest exemplu, dar nu şi în alte cazuri.

Când traducătorul face singur conversia, o astfel de conversie se


numeşte conversie implicită. Conversia făcută de noi înşişi se numeşte
conversie explicită.

Povestea despre conversiile tipurilor nu se termină aici, pentru că mai

© Copyright Link group 12 / 17


Curs: Core Java Programming
Modul: Bazele programării Java
Unitate: Tipuri de date

există nişte moduri în care putem converti tipurile. De exemplu,


Boxing şi Unboxing. Dar, vom mai vorbi despre aceste noţiuni abia
după ce stăpânim noţiunile de clase şi obiecte, căci atunci va fi mai
uşor să le înţelegem.

Exerciţiu 1

Problemă:

Este necesar să creăm o aplicaţie care adună două numere întregi. La


începutul aplicaţiei trebuie declarate două variabile pentru operanzi şi
una pentru operator. Variabilele nu trebuie iniţializate, aceasta se va
face mai târziu în program.

Soluţie:

Având în vedere că este vorba de operanzii numere întregi, putem


folosi tipurile Int. Operatorul va fi reprezentat printr-un caracter şi
pentru acest scop este adecvat tipul Char.

Codul va arăta aşa:

int a;
int b;
char op;

Exerciţiu 2

Problemă:

Creăm un modul. Este necesar să existe variabila care va urmări


statutul activităţii modulului (dacă acesta este activat sau dezactivat).
Această variabilă va subînţelege, iniţial, că modulul este activat.

© Copyright Link group 13 / 17


Curs: Core Java Programming
Modul: Bazele programării Java
Unitate: Tipuri de date

Soluţie:

Avem nevoie de variabila de tip boolean setată la valoarea true.

boolean status = true;

© Copyright Link group 14 / 17


Curs: Core Java Programming
Modul: Bazele programării Java
Unitate: Tipuri de date

CJP_04 - Core Java Programming


1. Ce conţine tipul char?
a) caracter
b) text
c) valoare numerică
d) valoare de un bit (corect sau incorect)
2. Ce conţine tipul de dată şir?
a) o secvenţă de valori de acelaşi tip
b) o valoare numerică
c) text
d) valoare de un bit (corect sau incorect)
3. Dacă dorim să stocăm o informaţie care arată dacă ceva
este corect sau incorect (0 sau 1) folosim tipul?
a) boolean
b) int
c) short
d) String
4. Ce se va întâmpla dacă încercăm să atribuim valoarea
2147483648 la o variabilă de tip short?
a) se va produce o eroare
b) variabilei se va atribui valoarea
c) nu se va întâmpla nimic şi valoarea nu se va atribui
5. Care este diferenţa între tipul int şi Integer?
a) int este tip simplu şi Integer este obiect
b) Integer este tip simplu şi int este obiect
c) nu este diferenţă
d) int este tip numeric şi Integer este tip textual
6. Ce conţine tipul de dată int?

© Copyright Link group 15 / 17


Curs: Core Java Programming
Modul: Bazele programării Java
Unitate: Tipuri de date

a) valoare totală
b) valoare cu virgulă mobilă
c) text
d) obiect

© Copyright Link group 16 / 17


Curs: Core Java Programming
Modul: Bazele programării Java
Unitate: Tipuri de date

1. Ce conţine tipul char?


a
2. Ce conţine tipul de dată şir?
a
3. Dacă dorim să stocăm o informaţie care arată dacă ceva
este corect sau incorect (0 sau 1) folosim tipul?
a
4. Ce se va întâmpla dacă încercăm să atribuim valoarea
2147483648 la o variabilă de tip short?
a
5. Care este diferenţa între tipul int şi Integer?
a
6. Ce conţine tipul de dată int?
a

© Copyright Link group 17 / 17

S-ar putea să vă placă și