2. Disclaimer & Acknowledgments
> Even though Ezequiel Aranda is a full-time employee of Sun
Microsystems, the contents here are created as his own
personal endeavor and thus does not reflect any official
stance of Sun Microsystems.
> Sun Microsystems is not responsible for any inaccuracies in
the contents.
> Acknowledgments – The slides of this presentation are made
from “SCJP Unit 7” by Warit Wanwithu and Thanisa
Kruawaisayawan and SCJP Workshop by P. Srikanth.
> This slides are Licensed under a Creative Commons
Attribution – Noncommercial – Share Alike 3.0
> http://creativecommons.org/licenses/by-nc-sa/3.0/
4. Generics
> a manera antigua:
L
List myList = new ArrayList();
myList.add(quot;Fredquot;);
myList.add(new Dog());
myList.add(new Integer(42));
> os métodos que obtenian los objetos de las
L
colecciones sólo podían tener un único tipo
de retorno: java.lang.Object
String s = (String) myList.get(0);
5. La manera nueva: Generics
List<String> myList = new
ArrayList<String>();
myList.add(quot;Fredquot;);
myList.add(new Dog()); // error
> stamos diciéndole al compilador que esta
E
colección solo puede contener Strings.
String s = myList.get(0);
6. La manera nueva: Generics (II)
> l tipo de los retornos puede ser declarado
E
como un generic también:
public Set<Dog> getDogList() {
Set<Dog> dogs = new
HashSet<Dog>();
// más código para insertar perros
return dogs;
}
7. Mezclando generics con non-
generics
List<Integer> myList = new
ArrayList<Integer>();
myList.add(4);
myList.add(6);
Adder adder = new Adder();
int total = adder.addAll(myList);
System.out.println(total);
8. class Adder {
int addAll(List list) {
Iterator it = list.iterator();
int total = 0;
while (it.hasNext()) {
int i =
((Integer)it.next()).intValue();
total += i;
}
return total;
}
}
9. List<Integer> myList = new
ArrayList<Integer>();
myList.add(4);
myList.add(6);
Inserter in = new Inserter();
in.insert(myList);
class Inserter {
void insert(List list) {
list.add(new String(quot;42quot;));
}
}
10. Mezclando generics con non-
generics
> todo eso, ¿Funciona?
Y
> amentablemente, si (compila y corre).
L
> e hecho, el compilador nos advertirá (a
D
través de un warning) de que estamos
corriendo un riesgo importante al enviar
nuestra lista genérica a un método que no lo
es.
> in embargo, un warning no es más que una
S
advertencia. Es decir, no se lo considera un
error.
11. Polimorfismo y generics
> udimos asignar un ArrayList a una referencia
P
a List porque List es un supertipo de ArrayList.
List<Integer> myList = new
ArrayList<Integer>();
> ero, ¿Podemos hacer esto?
P
class Parent { }
class Child extends Parent { }
List<Parent> myList = new
ArrayList<Child>();
12. Polimorfismo y Generics (II)
> n la declaración la regla es muy simple, el
E
tipo declarado en lado izquierdo debe ser el
mismo que el tipo en el lado derecho.
List<JButton> myList = new
ArrayList<JButton>();
List<Object> myList = new
ArrayList<Object>();
List<Integer> myList =
newArrayList<Integer>();
13. Métodos con Generics
public static void checkAnimals
(ArrayList<Animal> animals) {
for(Animal a : animals) {
a.checkup();}}
public static void main(String[] args) {
List<Dog> dogs = new ArrayList<Dog>();
List<Cat> cats = new ArrayList<Cat>();
List<Bird> birds = new ArrayList<Bird>();
checkAnimals(dogs); // List<Dog>
checkAnimals(cats); // List<Cat>
checkAnimals(birds); // List<Bird>
}
14. Métodos con Generics (II)
> o pueden asignarse ArrayLists de subtipos
N
de Animal al ArrayList del supertipo Animal.
> l compilador detendrá la compilación.
E
> a única cosa que puede pasarse como
L
parámetro en un método cuyo argumento sea
un ArrayList<Animal> será un
ArrayList<Animal>
15. Métodos con Generics (III)
public void addAnimal
(ArrayList<Animal> animals) {
animals.add(new Dog());
//a veces, vale...
}
> odríamos, sin embargo, hacer algo como lo
P
que se ve arriba, lo cual compilará siempre y
cuando lo que pasemos al método sea un
ArrayList<Animal>.
16. Métodos con Generics (IV)
> ay un mecanismo para “decirle” al
H
compilador que podemos aceptar cualquier
subtipo del argumento declarado en la
parametrización, porque no vamos a agregar
nada en la colección.
> icho mecanismo se llama “Wildcard”.
D
public void addAnimal(List<?
extends Animal> animals)
17. Métodos con Generics (V)
> on <? extends Animal> estamos diciendo
C
“aquí podemos asignar una colección que sea
un subtipo de List y/o este parametrizada con
un subtipo de Animal…”
> … Y prometemos no agregar nada a la
“
colección dentro de este método”.
public void addAnimal(List<?
extends Animal> animals) {
animals.add(new Dog());
// ¡NO! no podemos agregar nada
18. Métodos con Generics (VI)
> Hay una forma de usar un wildcard y
que nos sea permitido agregar
elementos a la colección: la palabra
“super”.
public static void addAnimal(List<? super
Dog> animals)
> Esencialmente, estamos diciendo “Don compilador,
acepte cualquier lista parametrizada con Dog o un
supertipo de Dog. Cualquier cosa más abajo en el
árbol de herencia, no; pero cualquier cosa más
arriba, sí”.
19. Métodos con Generics (VII)
public static void addAnimal(List<? super
Dog> animals) {
animals.add(new Dog());
}
public static void main(String[] args) {
List<Animal> animals = new
ArrayList<Animal>();
animals.add(new Dog());
addAnimal(animals);
}
21. Métodos con Generics (VIII)
public void foo(List<?> list) { }
> implemente significa “cualquier tipo”.
S
> ualquier List podría asignarse al argumento.
C
> in usar “super”, no podremos agregar nada
S
a list.
22. Métodos con Generics (IX)
public void foo(List<Object> list)
{}
> ignifica que el método solo puede tomar una
S
List<Object>, no una lista parametrizada en
algún subtipo de Object.
> in embargo, podremos agregar cosas a la
S
colección.
23. Pregunta
1) List<?> list = new ArrayList<Dog>();
2) List<? extends Animal> aList = new
ArrayList<Dog>();
3) List<?> foo = new ArrayList<? extends
Animal>();
4) List<? extends Dog> cList = new
ArrayList<Integer>();
5) List<? super Dog> bList = new
ArrayList<Animal>();
6) List<? super Animal> dList = new
ArrayList<Dog>();
> ¿Cuales compilan?
24. Declaraciones con Generics
public class Bucket<E>{ boolean
add(E o) }
> <E>” es una marcador de
“
sustitución para el tipo que
utilicemos. La interfaz List
funciona en este caso como
un template que, cuando
escribamos nuestro código,
cambiaremos por el tipo
deseado.
25. Declaraciones con Generics (II)
> n otras palabras, el tipo que utilicemos para
E
reemplazar ‘E’ cuando declaremos nuestras
instancias será lo que podamos agregar a las
colecciones involucradas.
Bucket<Animal> list = new
Bucket<Animal>();
> a ‘E’ pasa a ser un marcador de “coloque el
L
tipo deseado aquí” a ser específicamente el
tipo “Animal”, y el método add a comportarse
de la siguiente forma:
boolean add(Animal a)
26. import java.util.*;
public class RentalGeneric<T> {
private List<T> rentalPool;
private int maxNum;
public RentalGeneric( int maxNum, List<T>
rentalPool) {
this.maxNum = maxNum;
this.rentalPool = rentalPool;
}
public T getRental() {
return rentalPool.get(0);
}
public void returnRental(T returnedThing) {
rentalPool.add(returnedThing);
}
}
27. public class AnimalHolder<T extends
Animal>{
T animal;
public static void main(String[]
args) {
AnimalHolder<Dog> dogHolder =
new AnimalHolder<Dog>(); // OK
AnimalHolder<Integer> x = new
AnimalHolder<Integer>(); // KO
}
}
28. Creando Métodos parametrizados
import java.util.*;
public class CreateAnArrayList {
public <T> void makeArrayList(T t) {
/* Tomamos un objeto de un tipo
desconocido y usamos ‘T’ para representar
dicho tipo.*/
List<T> list = new ArrayList<T>();
// Ahora podemos crear la lista usando ‘T’
list.add(t);
}
}