Sunteți pe pagina 1din 2

O cafea nou...

babel

Tipuri GENERICE de date

n JAVA 5
Claudiu Soroiu
Java, ca orice limbaj de programare sau mai bine zis, aplicaie a evoluat de-a lungul timpului. Dei pn nu cu mult timp n urm cea mai nou versiune era 1.4.2 i se credea c va urma versiunea 1.5, s-a decis ca noua versiune s fie 5.0. Noua versiune ofer noi faciliti programatorilor pentru a-i ajuta s realizeze aplicaii mai stabile ntr-un timp mai scurt. Una dintre aceste faciliti o reprezint introducerea tipurilor generice. Aceast facilitate va fi prezentat n cadrul acestui articol. Vom ncepe mai nti prin a aminti faptul c ultima versiune de Java este 5.0, dei identificatorul de versiune se prezint sub forma 1.5.0. Dac n versiunea anterioar a platformei Java s-a dorit mbuntirea calitativ a setului standard de clase, de aceast dat platforma Java a suferit modificri la nivelul mainii virtuale. Genericitatea sau mai bine zis tipurile parametrizate reprezint un mecanism cu ajutorul cruia programatorii pot specifica tipul obiectelor cu care o anumit clas va opera prin intermediul parametrilor. Pentru a nelege mai bine acest concept, amintim c tipurile parametrizate de date sunt, ntr-o oarecare msur similare template-urilor din C++. Pentru a prezenta mai bine acest concept ne vom folosi de coleciile de date. n versiunile anterioare, coleciile de date puteau conine orice obiect, existnd oricnd riscul apariiei unei excepii la runtime de tipul ClassCastException datorit introducerii mai mult sau mai puin voluntare ntr-o colecie a unui obiect care are alt tip dect cel pentru care se folosea colecia respectiv. n continuare v vom prezenta un exemplu de program n care apare excepia amintit anterior:
import java.util.ArrayList; public class Test1 { static ArrayList a = new ArrayList(); public static void main (String[] args) { a.add("Gazeta"); a.add("de"); a.add(new Integer(4)); a.add("Informatica"); a.add("GInfo") print(); } public static void print() { for (int i = 0; i < a.size(); i++) { String s = (String) a.get(i); System.out.print(s + " "); } System.out.println(); } }

GInfo nr. 14/7 - noiembrie 2004

Codul anterior se compileaz corect, dar la execuie, n cadrul metodei print() este generat o excepie ClassCastException datorit faptului c un obiect de tipul Integer nu poate fi convertit la tipul String. n Java 5 tipul obiectelor care vor fi stocate ntr-o colecie poate fi precizat n momentul declarrii coleciei, astfel, codul urmtor poate fi transcris n Java 5 n:
import java.util.ArrayList; public class Test1 { static ArrayList<String> a = new ArrayList<String>(); public static void main (String[] args) { a.add("Gazeta"); a.add("de"); a.add(new Integer(4)); a.add("Informatica"); print(); a.add("GInfo") }

36

public static void print() { for (int i = 0; i < a.size(); i++) { String s = a.get(i); System.out.print(s + " "); } System.out.println(); } }

Acest cod nu poate fi compilat deoarece s-a declarat o colecie care conine obiecte de tipul String, iar n cadrul metodei main se ncearc adugarea unui obiect de tipul Integer. n momentul eliminrii unui obiect dintr-o colecie pentru care s-a specificat tipul obiectelor coninute, nu mai este necesar conversia rezultatului la tipul dorit. n metoda print, linia de cod a.get(i) returneaz un obiect de tipul String. n continuare vom prezenta modul n care se pot declara tipuri parametrizate de date:
public class NV <N,V> { private N name; private V value; public NV(N name, V value) { this.name = name; this.value = value; } public N getName() { return name; } public V getValue() { return value; } public static void main (String[] args) { NV<String, Integer> nv = new NV<String, Integer> ("Ionel", new Integer(4)); System.out.println( nv.getName()); System.out.println( nv.getValue()); } }

Dup cum se poate observa n cadrul codului anterior, pentru a declara parametrii unei clase se folosesc caracterele "<" i ">". ntre aceste caractere se afl lista parametrilor. O clas parametrizat poate fi folosit ca i cum nu ar fi parametrizat, implicit valoarea parametrilor fiind Object. Faptul c anumite clase sunt parametrizate este utilizat doar de compilatorul Java nu i de maina virtual, codul generat de compilatorul Java 5 putnd fi executat i de versiunea 1.4 a platformei. Domeniul de definiie al parametrilor unei clase poate fi restrns n sensul c poate fi specificat tipul acestora (clasele i/sau interfeele din care acetia trebuie s fie derivai). n continuare v prezentm un exemplu de clas ai crei parametri au fost restricionai:
public class NV <N,V extends Number> { private N name; private V value; public NV(N name, V value) { this.name = name; this.value = value; } public N getName() { return name; } public V getValue() { return value; } }

public class NV <N,V extends Number & Serializable>

Introducerea tipurilor parametrizate de date a dus la modificarea modului de declaraie a metodelor, astfel c pot apare secvene de cod ca:
void print(NV<? extends X, Y>);

sau
void print(NV<? super X, Y>).

babel
GInfo nr. 14/7 - noiembrie 2004

n cadrul primei declaraii, metoda print() primete ca parametru un obiect de tipul NV, iar primul parametru al clasei NV trebuie s fie derivat din X, unde X este un parametru al clasei curente. n cadrul primei declaraii, metoda print() primete ca parametru un obiect de tipul NV, iar primul parametru al clasei NV trebuie s fie printele lui X, unde X este un parametru al clasei curente. Parametrii claselor pot fi utilizai i pentru a arunca excepii n Java 5.
public interface Except <E extends Exception> { public void doRun() throws E; } public class Action implements Except<FileNotFoundException> { public void doWork() throws FileNotFoundException { new File("/foo/bar.txt"); } }

Un cod care ar conine o declaraie de forma: NV<String, Date> nu ar putea fi compilat deoarece cel de-al doilea parametru al clasei trebuie s extind clasa Number. Domeniul de definiie al parametrilor poate fi restrns astfel nct anumii parametri s implementeze mai multe interfee. O declaraie n care un parametru implementeaz mai multe interfee poate fi:

O clas poate s extind o clas parametrizat i/sau s suprascrie metode care se folosesc de parametrii clasei. Regula de baz n momentul motenirii unei clase sau suprascrierii unei metode este aceea c tipurile de date utilizate s fie subtipuri ale tipurilor definite n super-clasa sau ntr-o super-interfa. Dac nainte de Java 5 metodele care suprascriau alte metode trebuiau s returneze acelai tip de date, de aceast dat trebuie s returneze un tip de dat derivat din tipul de dat al metodei suprascrise.

37