Java Generico
Enviado por lazd01 • 6 de Febrero de 2013 • 2.727 Palabras (11 Páginas) • 375 Visitas
Generics en Java
« 10 comandos útiles para Linux que probablemente no conocías | Songbird 1.1 »
Antes de Java 5 cuando introducíamos objetos en una colección estos se guardaban como objetos de tipo Object, aprovechando el polimorfismo para poder introducir cualquier tipo de objeto en la colección. Esto nos obligaba a hacer un casting al tipo original al obtener los elementos de la colección.
view plaincopy to clipboardprint?
1. import java.util.ArrayList;
2. import java.util.List;
3.
4. public class Ejemplo {
5. public static void main(String[] args) {
6. List lista = new ArrayList();
7. lista.add("Hola mundo");
8.
9. String cadena = (String) lista.get(0);
10. System.out.println(cadena);
11. }
12. }
Esta forma de trabajar no solo nos ocasiona tener que escribir más código innecesariamente, sino que es propenso a errores porque carecemos de un sistema de comprobación de tipos. Si introdujeramos un objeto de tipo incorrecto el programa compilaría pero lanzaría una excepción en tiempo de ejecución al intentar convertir el objeto en String:
view plaincopy to clipboardprint?
1. import java.util.ArrayList;
2. import java.util.List;
3.
4. public class Ejemplo {
5. public static void main(String[] args) {
6. List lista = new ArrayList();
7. lista.add(22);
8.
9. String cadena = (String) lista.get(0);
10. System.out.println(cadena);
11. }
12. }
Podríamos utilizar el operador instanceof para comprobar el tipo del objeto antes de hacer el casting o antes de introducirlo en la colección, pero es poco elegante, añade aún más código a escribir, y no nos evitaría tener que hacer el casting.
Desde Java 5 contamos con una característica llamada generics que puede solventar esta clase de problemas. Los generics son una mejora al sistema de tipos que nos permite programar abstrayéndonos de los tipos de datos, de forma parecida a los templates o plantillas de C++ (pero mejor).
Gracias a los generics podemos especificar el tipo de objeto que introduciremos en la colección, de forma que el compilador conozca el tipo de objeto que vamos a utilizar, evitándonos así el casting. Además, gracias a esta información, el compilador podrá comprobar el tipo de los objetos que introducimos, y lanzar un error en tiempo de compilación si se intenta introducir un objeto de un tipo incompatible, en lugar de que se produzca una excepción en tiempo de ejecución.
Para utilizar generics con nuestras colecciones tan solo tenemos que indicar el tipo entre < y > a la hora de crearla. A estas clases a las que podemos pasar un tipo como "parámetro" se les llama clases parametrizadas, clases genéricas, definiciones genéricas o simplemente genéricas (generics). Veamos un ejemplo con la colección List.
view plaincopy to clipboardprint?
1. import java.util.ArrayList;
2. import java.util.List;
3.
4. public class Ejemplo {
5. public static void main(String[] args) {
6. List<String> lista = new ArrayList<String>();
7. lista.add("Hola mundo");
8.
9. String cadena = lista.get(0);
10. System.out.println(cadena);
11. }
12. }
Este código, sin embargo, no compilaría, dado que hemos indicado que nuestra colección contendrá objetos de tipo String, y no Integer:
view plaincopy to clipboardprint?
1. import java.util.ArrayList;
2. import java.util.List;
3.
4. public class Ejemplo {
5. public static void main(String[] args) {
6. List<String> lista = new ArrayList<String>();
7. lista.add(new Integer(22));
8.
9. Integer numero = lista.get(0);
10. System.out.println(numero);
11. }
12. }
Algo a tener en cuenta es que el tipo parámetro debe ser una clase; no podemos utilizar tipos primitivos. Esto, sin embargo, no es ningún problema gracias a las características de autoboxing y unboxing de Java 5. En el código siguiente, por ejemplo, se crea un objeto Integer intermedio de forma transparente, que es el objeto que se introducirá en realidad en la colección, y no un int de valor 22, como podría parecer. Posteriormente el objeto Integer se vuelve a convertir en int automáticamente.
view plaincopy to clipboardprint?
1. import java.util.ArrayList;
2. import java.util.List;
3.
4. public class Ejemplo {
5. public static void main(String[] args) {
6. List<Integer> lista = new ArrayList<Integer>();
7. lista.add(22);
8.
9. int numero = lista.get(0);
10. System.out.println(numero);
11. }
12. }
Ahora, ¿cómo podemos crear nuestras propias clases parametrizadas? ¿cómo funciona a partir de Java 5 una colección como List? Sencillo. Solo tenemos que añadir el tipo parámetro después del nombre de la clase, y utilizar el nombre de este tipo genérico donde usaríamos un tipo concreto (con algunas excepciones). Por convención se suele utilizar una sola letra mayúscula para el tipo genérico.
Como ejemplo vamos a crear una pequeña clase que almacene un objeto, con su getter y setter, y que permita imprimir la cadena que lo representa, o bien imprimir la cadena al revés:
view plaincopy to clipboardprint?
1. public class Imprimidor<T> {
2. private T objeto;
3.
4. public Imprimidor(T objeto) {
5. this.objeto = objeto;
6. }
7.
8. public void setObjeto(T objeto) {
9. this.objeto = objeto;
10. }
11.
12. public T getObjeto() {
13. return objeto;
14. }
15.
16. public void imprimir() {
17. System.out.println(objeto.toString());
18. }
19.
20. public void imprimir_reves() {
21. StringBuffer sb = new StringBuffer(objeto.toString());
22. System.out.println(sb.reverse());
23. }
24. }
Ahora podríamos utilizar nuestra nueva clase de la misma forma que hacíamos con List:
view plaincopy to clipboardprint?
1. public class Ejemplo
...