Sunteți pe pagina 1din 8

Programare Java Lucrarea de laborator Nr.

INTRODUCERE N LIMBAJUL JAVA


Java nu este numai un limbaj de programare, Java este o tehnologie care ofera suport dezvoltarii aplicatiilor distribuite, independente de platforma. Java ca limbaj si mediu de programare a fost lansat si este n continuare sustinut de firma Sun Microsystems . Cea mai mare parte a sintaxei de programare Java este mostenita de la C++, dar unele din conceptele de programare obiectuala prezente n Java si au radacinile n limbajele SmallTalk si Lisp. Limbajul Java are cteva caracteristici care l fac un limbaj de succes pe piata actuala de software. Astfel, limbajul Java poate fi caracterizat ca un limbaj simplu, familiar, robust, orientat pe obiecte, independent de platforma, adaptat pentru aplicatii distribuite si care asigura un nivel ridicat de securitate. Spre deosebire de C++, limbajul Java este n intregime orientat pe obiecte. n orice aplicatie trebuie sa existe cel putin o clasa si nu se pot defini variabile sau functii care sa apartina unei clase. n plus, Java mareste gradul de siguranta al codului prin existenta a doua nivele de verificare: unul la compilare si unul la rulare. Accesul la tablourile Java este verificat la rulare eliminand astfel posibilitatea accesului accidental n afara domeniului tabloului. Conversiile ntre tipurile de date sunt restrictionate, evitndu-se astfel scrierea nepermisa a unor zone de memorie. Programele executabile Java, numite si bytecodes sunt rezultatul compilarii unui program sursa. Pentru a putea fi executate pe o anumita platforma (Windows, Unix) acestea au nevoie de un emulator Java Virtual Machine (JVM) specific respectivei platforme. Ca urmare a utilizarii emulatorului, un program Java poate rula pe orice platforma n care se poate executa o masina virtuala Java. O categorie speciala de programe Java o reprezinta categoria applet-urilor care sunt programe Java ce se executa n cadrul unui browser Internet (Netscape Navigator, Internet Explorer). La baza dezvoltarii unui program Java sta mediul de dezvoltare pus la dispozitie de firma Sun. Acesta este Java Developers Kit (JDK). Exista medii integrate puternice de dezvoltare, depanare si testare a unei aplicatii Java, dar n cadrul laboratorului se vor folosi uneltele standard de programare utilizand mediul JDK pus la dispozitie de firma Sun. Mediul jdk este disponibil pe Internet la adresa http://java.sun.com, freeware, n diverse versiuni si variante n functie de platforma de lucru (Windows, Solaris, etc.). Mediul JDK contine pe de o parte o serie de biblioteci de clase Java necesare scrierii unui program si pe de alta parte un set de utilitare necesare compilarii, testarii, executiei si documentarii unei aplicatii Java. O clasa, un fisier bytecode cu extensia .class , reprezinta unitatea fundamentala a unui program executabil Java. O biblioteca de clase cuprinde o serie de clase ce au functionalitati . O astfel de biblioteca este cunoscuta n Java sub numele de package . JDK include cateva package-uri fundamentale care contin clase fara de care nu se pot dezvolta aplicatii Java. De exemplu, package-ul java.lang contine clasele fundamentale fara de care un program Java nu poate exista. Acest package este inclus automat de compilator fara a fi nevoie de precizari suplimentare. Utilizarea unei clase din oricare alt package decat java.lang intr-un program Java se specifica prin directiva import nume_package.* sau import nume_package.nume_clasa . Dintre programele de dezvoltare puse la dispozitia programatorului amintim: javac este compilatorul Java care transforma sursele text scrise n limbaj de programare Java n cod executabil pe masina virtuala. Fisierul sursa, cu extensia .java se transmite ca si parametru n programul javac. Vor rezulta o serie de fisiere cu extensia .class, n functie de numarul de clase definite n fisierul sursa. java este interpretorul Java care executa programele Java (fisierele .class). Este util doar pentru executia aplicatiilor Java stand-alone nu si a applet-urilor. Are ca parametru numele fisierului (fara extensia .class) rezultat n urma compilarii.

1.1

DEZVOLTAREA SI EXECUTIA UNEI APLICATII INDEPENDENTE JAVA

Etapele n crearea si lansarea n executie a unei aplicatii Java sunt : scrierea codului, compilarea, interpretarea si lansarea n executie. Editarea unui program Java se poate face utilizand orice editor simplu de text, care salveaza datele n format text. Un exemplu ar fi folosirea utilitarului Notepad . In acest caz insa, dupa editarea programului si salvarea lui intr-un fisier cu extensia .java ar urma compilarea si lansarea n executie prin apelarea explicita a utilitarelor prezentate mai sus.

Este mai usor insa sa se foloseasca toolset-uri (sisteme) de dezvoltare, dintre care multe se gasesc gratuit in Internet, cum sunt Textpad sau Eclipse. Aceste sisteme de dezvoltare ofera mai multe facilitati cum sunt: editarea fisierelor sursa cu optiuni de highlight a cuvintelor cheie ale limbajului, compilarea si rularea programelor, cu afisarea erorilor sau a rezultatelor wexecutiei. De asemenea, aceste sisteme de dezvoltare dispun de comezi care permit adaugarea si selectarea optiunilor de editare, compilare si rulare a programelor. Un exemplu de fisier sursa Java este fisierul Hello.java care contine urmatoarele linii de cod:
/* * Programul afiseaza textul Hello si se incheie */ public class Hello{ public static void main (String args[]){ System.out.println(Hello); } }

Una din conditiile ca fisierul sursa Java sa poata fi utilizat mai departe (compilat) este sa aiba extensia .java. In programul de mai sus e cuprins un comentariu /* */ care se poate extinde pe mai multe linii si pe care compilatorul nu ]l ia n considerare. Ca si n C++, un alt tip de comentariu este //, comentariu de linie. Fisierul trebuie sa contina o declaratie de clasa. Pe scurt, o clasa este un tip de date generic, care pe langa date (numite si membrii) reprezentand starea, contine si functii (metode) ce reprezinta functionalitatea. Materializarea (instanta ) unei clase se numeste obiect. Avnd public class n declaratia clasei este obligatoriu ca fisierul sa aiba numele clasei. In cazul dezvoltarii aplicatiilor (nu si a applet-urilor) clasa trebuie sa contina metoda main() de forma :
public static void main (String args[]){. . .}

Aceasta metoda trebuie sa existe n orice aplicatie Java, fiind prima metoda apelata cand se lanseaza n executie un program (un bytecode ) Java. Termenul public este un cuvant cheie al limbajului Java si n acest context indica faptul ca metoda main() este o metoda publica, adica poate fi apelata din exteriorul clasei. Datorita cuvntului cheie static, metoda main() este o metoda legata de clasa Hello si nu de un obiect, de o instanta a ei. args[] este un tablou de siruri de caractere (String) si reprezinta parametrii din linia de comanda ai programului apelat. In interiorul metodei main se scrie ceea ce se doreste ca programul sa faca, n acest caz, afisarea sirului Hello . System este o clasa care contine un membru static out caruia i se poate apela o metoda println() care are ca parametru sirul de tiparit. Daca operatia de compilare se face cu success (nu apare nici un mesaj de eroare), se obtine un nou fisier Hello.class, fisier care contine programul executabil Java.

1.2

STRUCTURA LEXICALA A UNUI PROGRAM JAVA

Structura si gramatica unui program Java se aseamana foarte mult cu cea a unui program C++. Limbajul Java contine urmatoarele unitati lexicale: Comentarii ofera posibilitatea documentarii programului n vederea unei ntelegeri mai usoare a programului sursa. Cuvinte cheie sunt cuvinte care au un sens special n limbaj si insotesc variabilele, metodele, membrii, clasele etc. Java dispune de urmatoarele cuvinte cheie (keywords):
abstract boolean break byte case catch char class const continue default do double else extends final finally float for package if implements import instanceof int interface long native new this private throw protected throws public transient return try short void static volatile super while switch synchronized

Identificatorii sunt siruri de caractere si reprezinta numele dat unei variabile, clase sau unei functii. Conditii: sirul ncepe cu o litera; sirul este diferit de orice cuvnt cheie; sirul este diferit de null, false, true. Desi nu exista o regula obligatorii pentru scrierea identificatorilor, exista
2

anumite conventii utilizate: identificatorii numelor de clase ncep cu majuscula, fiecare cuvnt distinct din identificator ncepe cu majuscula; identificatorii de variabila ncep cu litera mica, fiecare cuvnt care urmeaza ncepe cu majuscula; identificatorii unei functii respecta regula de la variabile. Literalii reprezinta valori constante de diferite tipuri de date primitive (ntreg, caracter etc). Separatorii sunt utilizati pentru a separa unitatile lexicale unele de altele. Acestia sunt: ( ) { } [ ] ; , . Operatori- sunt necesari pentru a realiza operatiile care se aplica asupra unor date din program.

1.3

TIPURI DE DATE, OPERATORI SI INSTRUCTIUNI


Tipuri de date primitive reprezinta acele date care sunt incluse implicit n limbajul Java. Sunt tipuri numerice intregi (byte, short, int, long, char), tipuri numerice reale (float, double) si tipul boolean (boolean). Tipuri de date referinta sunt clasele, tablourile si interfetele . Ca si n limbajul C++, clasele reprezinta tipuri generice de date caracterizate printr-o stare definite de atributele clasei si printro functionalitate definite de metodele clasei; tablourile sunt colectii de date de acelasi tip, iar interfetele sunt un fel de clase abstacte si vor fi studiate n lucrarea urmatoare.

Tipurile de date din Java se clasifica n doua categorii:

Variabilele de tip primitiv se pot crea numai prin declaratie (care este n acelasi timp si o definitie). Variabilele de tip referinta se pot crea cu operatorul new , care (spre deosebire de C++) returneaza o referinta. O referinta Java este un identificator al unui obiect si este, de fapt un pointer ascuns, asemanator cu o referinta C++, de care se deosebeste n primul rnd din punct de vedere sintactic (nu se mai foloseste operatorul & la definitia unei referinte). Deoarece nu se pot defini referinte pentru tipurile primitive, n pachetul java.lang sunt definite mai multe clase care ncconjora tipurile primitive, adic a au ca data membru o variabila de tipul primitiv respectiv. Aceste clase sunt Byte, Short, Integer, Character, Float, Double etc. Majoritatea acestor clase (cu exceptia claselor Integer si Character) au aceeasi denumire ca si tipul de date primitive corespunzator, cu primul caracter modificat n majuscula. Cteva exemple de creare de variabile de tip primitiv si de tip referinta sunt date n programul urmator (Tipuri.java)
// // Tipuri.java // class Numar{ int n; Numar(int x){n=x;} } public class Tipuri{ public static void main(String[] args) { int x = 10; Integer i1 = new Integer(100); Byte b1 = new Byte((byte)20); Character c1 = new Character('A'); Numar n1 = new Numar(7); System.out.println("int: " + x); System.out.println("Integer: " + i1); System.out.println("Byte: " + b1); System.out.println("Character: " + c1); System.out.println("Numar: " + n1.n); } }

n acest program se creaza o variabila de tip primitiv (ntreg - int) prin definitie (declaratie) si mai multe obiecte de tipul claselor Integer , Byte , Character , Numar , folosind operatorul new. Fiecare variabila creata se afiseaza la consola folosind functia System.out.println(). Clasa Numar este o clasa

noua creata n program, asa cum se vede n listing. La executia acestui program se obtin urmatoarele linii afisate la consola :

Clasa Object. n Java este este implementat un mecanism de mostenire simpla, prin care o clasa poate extinde (deriva) o singura clasa de baza, iar ierarhia de clase care se creeaza are o radacina unica, clasa Object din pachetul java.lang. Daca n program se defineste o clasa care nu este derivata din nici o alta clasa, atunci, n mod implicit, ea extinde clasa Object, ceea ce nseamna ca, de exemplu definitia class X{. . .} este echivalenta cu definitia class X extends Object{. . .}. Clasa Object defineste metode de baza pentru manevrarea obiectelor, metode care trebuie sa fie redefinite n clasele derivate. Cele mai importante dintre a cestea sunt:
public class Object{ public String toString(); public boolean equals(Object obj); protected Object clone() throws CloneNotSupportedException; .. }

Metoda toString() returneaza un String caracteristic clasei. Metoda trebuie sa fie redefinita n fiecare clasa derivata din clasa Object. Prin redefinire, metoda equals()poate fi utilizata pentru a compara doua obiecte (pentru a vedea daca sunt identice din punctul de vedere al atributelor lor). Prin metoda clone() se creaza (prin copiere) un obiect de aceeasi clasa cu obiectul din care se apeleaza metoda. Pentru a putea aplica aceasta metoda trebuie ca acea clasa sa implementeze interfata Cloneable si, n plus, sa redefineasa metoda clone(). n cazul n care se ncearca o copiere a unui obiect, dar clasa obiectului respectiv nu implementeaza Cloneable, se va arunca o exceptie de tipul CloneNotSupportedException.

Operatorii Java se sunt n cea mai mare parte aceeasi cu cei din C++, cu cteva deosebiri. Operatorii delete , & (addressof), * (dereferentiere) si :: (rezolutie) au disparut. A aparut un operator nou (instanceof). Acesta este utilizat pentru a testa daca un obiect este o instanta a unei anumite clase. Forma generala a acestui operator este:
nume_obiect instanceof nume_clasa

Operatorul instanceof returneaza true daca obiectul (cu referinta nume_obiect) este o instanta clasei nume_clasa sau a unei superclase a acesteia; n caz contrar, returneaza false. Exemplu:
class X {...} class Y extends X{...} class Z {...} X objX = new X(); Y objY = new Y(); Z objZ = new Z(); System.out.println(objX instanceof X); System.out.println(objX instanceof Object); System.out.println(objX instanceof Z);

// afiseaza: true // afiseaza: true // afiseaza: false

Operatorul de asignare (=) se comporta la fel ca n C++ pentru tipurile primitive (se copiaza valoarea variabilei). Pentru tipurile referinta, nsa, se copiaza referintele, nu obiectele referite, iar pentru copierea

obiectelor trebuie sa se foloseasca functia clone(). Functia clone() care este definita n clasa Object si trebuie sa fie redefinita n orice clasa pentru care este necesara copierea obiectelor. Operatorul de comparatie de egalitate (==) se comporta la fel ca n C++ pentru tipurile primitive (se compara valorile variabilelor). Pentru tipurile referinta, operatorul == compara referintele, nu obiectele referite, iar pentru comparatia chiar a obiectelor, trebuie sa se foloseasca functia equals(). Functia equals() este definita n clasa de baza Object si trebuie sa fie redefinita pentru oricare clasa pentru care este necesara comparatia obiectelor. Operatorul + suprancarcat pentru clasa String . n Java nu este admisa suprancarcarea operatorilor, cu exceptia operatorului de adunare pentru clasa String. Clasa String (din pachetul java.lang) contine un sir de caractere si numeroase metode pentru operatii asupra acestora. Operatorul de adunare suprancarcat pentru clasa String admite trei forme de apel:
sir + var, var + sir si sir1 + sir2 .

n urma acestei operatii se obtine un obiect sir de caractere (String) care contine un sir de caractere format prin conatenarea celor doua subsiruri corespunzatoare celor doi operanzi. Se considera ca operandul denumit sir (sau sir1, sir2) este o constanta (literal) sir de caractere (de exemplu, abcde) sau o referinta la un obiect String. n cazul n care variabila var este o referinta la un obiect, se utilizeaza metoda toString() a clasei obiectului (daca este redefinita n acea clasa) sau metoda toString() mostenita de la clasa Object pentru a obtine subsirul care intervine n operatie. Exemple:
String sir1 = ABC, sir2; int a = 2; float b=14.32f; boolean c = true; Object obj = new Object(); sir2 = sir1 + a; System.out.println(sir2); sir2 = XYZ + b; System.out.println(sir2); sir2 = c + sir1; System.out.println(sir2); sir2 = sir1 + obj; System.out.println(sir2);

// afisare: ABC2 // afisare: XYZ14.32 // afisare: trueABC // afisare: ABCObject@12123

Metoda toString() mostenita din clasa Object returneaza numele clasei si o valoare de identificare unica a obiectului (hash code ), valoare alocata de masina virtuala n mod unic unui obiect. De obicei functia toString() se redefineste pentru fiecare clasa. Instructiunile Java sunt foarte asemanatoare cu instructiunile C/C++ si sunt urmatoarele: if else, switch , for, while, do , break , continue , return. Exista doua mari diferente fata de limbajul C/C++. O deosebire priveste instructunile ce implica expresii conditionale din instructiunile if else, for, while, do. Daca n C aceste expresii puteau fi de tip int , n Java ele trebuie sa fie strict de tipul boolean (n Java nu este posibila conversia din int n boolean). O alta deosebire este legata de instructiunea goto care lipseste n Java fiind substituita de instructiunile break si continue care pot primi o eticheta de salt.

1.4

TABLOURI

Un tablou (array) este o lista de elemente de acelasi tip plasate ntr-o zona continua de memorie, care pot fi adresate utiliznd un nume, un identificator comun. Tipul elementelor din tablou trebuie sa fie de acelasi tip si poate fi oricare tip primitiv sau tip referinta. Un tablou Java este un tip referinta, deci identificatorul (numele) unui tablou reprezinta o referinta (o adresa) la locatia unde se gaseste ntregul tablou de elemente. Un tablou Java este un obiect care contine, n afara de elementele tabloului o variabila membra publica length din care se poate citi (nu si scrie) dimensiunea tabloului. Tablourile pot fi definite pentru tipuri primitive sau pot contine referinte la obiecte (clase). Tablourile de date primitive contin chiar acele date memorate n elementele tabloului, iar tablourile de obiecte (tip referinta) contin referinse memorate n elementele tabloului. Dimensiunile unui tablou sunt fixe (nu se mai pot modifica dupa creare).

Prin declararea unui tablou se creaza o variabila referinta avnd valoarea null (care nu refera nimic). Nu se aloca spatiu pentru elementele tabloului. Forma generala de declarare a unui tablou unidimensional este:
tip nume_tablou[]; tip[] nume_tablou; //sau

Exemple:
int[] tabInt; String tabString[]; Object[] tabObjects;

Dupa declararea unui tablou urmeaza instantierea lui, adica alocarea zonei de memorie necesara stocarii elementelor lui. Instantierea unui tablou se poate face n doua moduri. Cel mai utilizat mod este prin utilizarea lui new astfel:
nume_tablou = new tip[nr_el];

n acest mod s-a alocat o zona de memorie necesara stocarii unui numar de nr_el, zona care poate fi adresata prin referinta nume_tablou. Tot acum se aloca variabila length care va contine lungimea tabloului (numarul de elemente ale tabloului). Elementele tabloului contin datele de tip primitiv sau referinte la obiecte si sunt initializate la valori implicite. Elementelor de tip numeric li se va atribuie valoarea 0, celor de tip boolean valoarea false, celor de tip char valoarea spatiu liber (blanc), iar celor de tip referinta valoarea null. Un alt mod de instantiere a unui tablou si care este valabil doar n momentul declaratiei lui este urmatorul:
tip nume[] = {el1, el2, ....elN};

Prin aceasta constructie se aloca spatiu elementelor tabloului (la fel ca si n cazul utilizarii operatorului new) si se atribuie elementelor valorile specificate n lista de initializare (altele dect cele implicite) elementelor din tablou. Dimeniunea tabloului rezulta din numarul de elemente din lista de initializare. Elementele unui tablou se pot accesa folosind operatorul de indexare ([]). Exemple:
int[] tabInt = new int[10]; int x = tabInt[2]; long tabLong[] = new long[4]; char tabChar[]={t,a,b,l,e};

Indexul care se foloseste n operatia de indexare trebuie sa aiba o valoare ntreaga pozitiva, cuprinsa ntre 0 si length-1. Daca valoarea indexului nu este pozitiva sau depaseste dimensiunea tabloului, n cursul executiei se va arunca o exceptie java.lang.ArrayIndexOutOfBoundsException. Un tablou de referinte la obiecte se creeaza la fel ca si un tablou de date de tip primitiv. La crearea unui astfel tablou cu operatorul new, elementele tabloului (care sunt referinte) sunt initializate cu valoarea null. La crearea folosind o expresie de initializare, se initializeaza fiecare element al tabloului cu referinta obiectului respectiv. De exemplu:
Integer []t1 = new Integer[5]; Integer []t2 = {new Integer(0), new Integer(1), new Integer(2)};

Un tablou multidimensional este implementat ca un tablou de tablouri. Pentru a initializa un tablou multidimensional se poate folosi operatorul new sau o lista de initializare la fel ca si n cazul tabloului unidimensional. Exemple:
int [][]tab1; tab1 = new int[2][3]; int [][]tab2 = {{2,3,4}, {3,4,5}}; int [] tab3[];

// se declara si se instantiaza // un tablou bidimensional //declaratie echivalenta cu int[][] tab3;

Clasa Arrays. n pachetul java.util exitsa clasa Arrays care contine mai multe metode statice care pot fi apelate pentru operatii asupra elementelor din tablouri. Cteva dintre aceste metode sunt:

fill(tip[], val), pentru umplerea unui tablou de date de tipul tip cu valoarea val (de

acelasi tip dat). Exista mai multe vesiuni suprancarcate, pentru tipuri primitive si pentru referinte (la clasa de baza Object): fill(int[] a, int v) , fill(Object[] a, Object v).
equals(tip[] a, tip[] v), returneaza true daca cele doua tablouri (de date de acelasi

tip) au toate elementele egale.


sort(tip[] a) , sorteaza elementele vectorului a (care contine elemente de tipul tip).

n exemplul urmator (Tablouri.java) se creeaza cteva tablouri de diferite tipuri (boolean, int etc.) care se initializeaza folosind metoda fill() a clasei Arrays si se listeaza. Pentru listarea elementelor s-au scris cteva metode de conversie suprancarcate pentru tablouri de elemente de diferite tipuri (metodele toString()).
// // Tablouri.java // import java.util.*; class Numar{ int n; public Numar(int k){ n = k; } public String toString(){ return "n = " + n;} } public class FillingArrays { public static String toString(boolean[] a) { StringBuffer result = new StringBuffer("["); for(int i = 0; i < a.length; i++) { result.append(a[i]); if(i < a.length - 1) result.append(", "); } result.append("]"); return result.toString(); } public static String toString(char[] a) { StringBuffer result = new StringBuffer("["); for(int i = 0; i < a.length; i++) { result.append(a[i]); if(i < a.length - 1) result.append(", "); } result.append("]"); return result.toString(); } public static String toString(int[] a) { StringBuffer result = new StringBuffer("["); for(int i = 0; i < a.length; i++) { result.append(a[i]); if(i < a.length - 1) result.append(", "); } result.append("]"); return result.toString(); } public static String toString(Numar[] a){ StringBuffer result = new StringBuffer("["); for(int i = 0; i < a.length; i++) { result.append(a[i]); if(i < a.length - 1) result.append(", "); } result.append("]");

return result.toString(); } public static void main(String[] args) { int size = 6; boolean[] a1 = new boolean[size]; char[] a2 = new char[size]; int[] a3 = new int[size]; Numar[] a4 = new Numar[size]; Numar n1 = new Numar(7); Arrays.fill(a1, true); Arrays.fill(a2, 'A'); Arrays.fill(a3, 10); Arrays.fill(a4, n1); System.out.println(toString(a1)); System.out.println(toString(a2)); System.out.println(toString(a3)); System.out.println(toString(a4)); } }

La executia acestui program se obtine urmatorul rezultat:

EXERCITII
1.1 Introduceti, compilati si executati programul Tipuri.java. Testati diferite situatii si urmariti erorile de compilare pe care le obtineti daca adaugati n program linii suplimentare, ca de exemplu:
int y = new int(); Numar & n2 = new Numar();

1.2 Creati un tablou bidimensional de dimensiune 5x5 de numere de tip ntreg n care numerele din prima coloana sunt multipli consecutivi ai lui 10 iar elementele consecutive din linii sunt crescatoare cu o unitate. Afisati elementele tabloului. Afisati elementul (2,3). 1.3 Se da urmatorul tablou de cuvinte (siruri de caractere): Martie,Aprilie, Luna, An. Sa se afiseze cte un mesaj care sa specifice cu ce litera ncepe fiecare cuvnt dat, folosind instructiunea switch (aceeasi ca n C++). 1.4 Introduceti, compilati si executati programul Tablouri.java. Comentati liniile de ncarcare a tablourilor cu o valoare data ( Arrays.fill(a1, true)...) si observati cum se face initializarea implicita a elementelor tablourilor. Modificati programul astfel nct fiecare element al tabloului a4 sa refere un obiect (de clasa Numar) a carui variabila membra (n) are valoarea egala cu indexul elementului.