Вы находитесь на странице: 1из 29

SCJP 6

Clase 7 Generics

Ezequiel Aranda
Sun Microsystems Campus
Ambassador

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/

AGENDA
>Generics
>Mtodos con generics
>Declaraciones con generics

Generics
>La manera antigua:
List myList = new ArrayList();
myList.add("Fred");
myList.add(new Dog());
myList.add(new Integer(42));

>Los mtodos que obtenian los objetos de las


colecciones slo podan tener un nico tipo
de retorno: java.lang.Object
String s = (String) myList.get(0);

La manera nueva: Generics


List<String> myList = new
ArrayList<String>();
myList.add("Fred");
myList.add(new Dog()); // error

>Estamos dicindole al compilador que esta


coleccin solo puede contener Strings.
String s = myList.get(0);

La manera nueva: Generics (II)


>El tipo de los retornos puede ser declarado
como un generic tambin:
public Set<Dog> getDogList() {
Set<Dog> dogs = new
HashSet<Dog>();
// ms cdigo para insertar perros
return dogs;
}

Mezclando generics con nongenerics


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);

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;
}
}

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("42"));
}
}

Mezclando generics con nongenerics

>Y todo eso, Funciona?


>Lamentablemente, si (compila y corre).
>De hecho, el compilador nos advertir (a
travs de un warning) de que estamos
corriendo un riesgo importante al enviar
nuestra lista genrica a un mtodo que no lo
es.
>Sin embargo, un warning no es ms que una
advertencia. Es decir, no se lo considera un
error.

Polimorfismo y generics
>Pudimos asignar un ArrayList a una referencia
a List porque List es un supertipo de ArrayList.
List<Integer> myList = new
ArrayList<Integer>();

>Pero, Podemos hacer esto?


class Parent { }
class Child extends Parent { }
List<Parent> myList = new
ArrayList<Child>();

Polimorfismo y Generics (II)


>En la declaracin la regla es muy simple, el
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>();

Mtodos 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>
}

Mtodos con Generics (II)


>No pueden asignarse ArrayLists de subtipos
de Animal al ArrayList del supertipo Animal.
>El compilador detendr la compilacin.
>La nica cosa que puede pasarse como
parmetro en un mtodo cuyo argumento sea
un ArrayList<Animal> ser un
ArrayList<Animal>

Mtodos con Generics (III)


public void addAnimal
(ArrayList<Animal> animals) {
animals.add(new Dog());
//a veces, vale...
}

>Podramos, sin embargo, hacer algo como lo


que se ve arriba, lo cual compilar siempre y
cuando lo que pasemos al mtodo sea un
ArrayList<Animal>.

Mtodos con Generics (IV)


>Hay un mecanismo para decirle al
compilador que podemos aceptar cualquier
subtipo del argumento declarado en la
parametrizacin, porque no vamos a agregar
nada en la coleccin.
>Dicho mecanismo se llama Wildcard.
public void addAnimal(List<?
extends Animal> animals)

Mtodos con Generics (V)


>Con <? extends Animal> estamos diciendo
aqu podemos asignar una coleccin que sea
un subtipo de List y/o este parametrizada con
un subtipo de Animal
> Y prometemos no agregar nada a la
coleccin dentro de este mtodo.
public void addAnimal(List<?
extends Animal> animals) {
animals.add(new Dog());
// NO! no podemos agregar nada

Mtodos con Generics (VI)


>Hay una forma de usar un wildcard y
que nos sea permitido agregar
elementos a la coleccin: 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 ms abajo en el
rbol de herencia, no; pero cualquier cosa ms
arriba, s.

Mtodos 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);
}

Pregunta
>public void foo(List<?> list) { }
>public void foo(List<Object> list)
{ }

>En que se diferencian?

Mtodos con Generics (VIII)


public void foo(List<?> list) { }

>Simplemente significa cualquier tipo.


>Cualquier List podra asignarse al argumento.
>Sin usar super, no podremos agregar nada
a list.

Mtodos con Generics (IX)


public void foo(List<Object> list)
{}

>Significa que el mtodo solo puede tomar una


List<Object>, no una lista parametrizada en
algn subtipo de Object.
>Sin embargo, podremos agregar cosas a la
coleccin.

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?

Declaraciones con Generics


public class Bucket<E>{ boolean
add(E o) }

><E> es una marcador de


sustitucin para el tipo que
utilicemos. La interfaz List
funciona en este caso como
un template que, cuando
escribamos nuestro cdigo,
cambiaremos por el tipo
deseado.

Declaraciones con Generics (II)


>En otras palabras, el tipo que utilicemos para
reemplazar E cuando declaremos nuestras
instancias ser lo que podamos agregar a las
colecciones involucradas.
Bucket<Animal> list = new
Bucket<Animal>();

>La E pasa a ser un marcador de coloque el


tipo deseado aqu a ser especficamente el
tipo Animal, y el mtodo add a comportarse
de la siguiente forma:
boolean add(Animal a)

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);
}
}

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
}
}

Creando Mtodos 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);
}
}

Preguntas

Вам также может понравиться