clase7 generics

29
SCJP 6 Clase 7 – Generics Ezequiel Aranda Sun Microsystems Campus Ambassador

Upload: jorgmarq

Post on 26-May-2015

303 views

Category:

Documents


6 download

TRANSCRIPT

Page 1: Clase7 generics

SCJP 6 Clase 7 – Generics

Ezequiel Aranda

Sun Microsystems Campus Ambassador

Page 2: Clase7 generics

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/

Page 3: Clase7 generics

AGENDA

>!Generics

>!Métodos con generics

>!Declaraciones con generics

Page 4: Clase7 generics

Generics

>!La manera antigua:

List myList = new ArrayList();

myList.add("Fred");

myList.add(new Dog());

myList.add(new Integer(42));

>!Los métodos que obtenian los objetos de las colecciones sólo podían tener un único tipo de retorno: java.lang.Object

String s = (String) myList.get(0);

Page 5: Clase7 generics

La manera nueva: Generics

List<String> myList = new

ArrayList<String>();

myList.add("Fred");

myList.add(new Dog()); // error

>!Estamos diciéndole al compilador que esta colección solo puede contener Strings.

String s = myList.get(0);

Page 6: Clase7 generics

La manera nueva: Generics (II)

>!El tipo de los retornos puede ser declarado como un generic también:

public Set<Dog> getDogList() {

Set<Dog> dogs = new

HashSet<Dog>();

// más código para insertar perros

return dogs;

}

Page 7: Clase7 generics

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

Page 8: Clase7 generics

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;

}

}

Page 9: Clase7 generics

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

}

}

Page 10: Clase7 generics

Mezclando generics con non-generics

>!Y todo eso, ¿Funciona?

>!Lamentablemente, si (compila y corre).

>!De hecho, el compilador nos advertirá (a 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.

>!Sin embargo, un warning no es más que una advertencia. Es decir, no se lo considera un error.

Page 11: Clase7 generics

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

Page 12: Clase7 generics

Polimorfismo y Generics (II)

>!En la declaración 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>();

Page 13: Clase7 generics

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>

}

Page 14: Clase7 generics

Métodos con Generics (II)

>!No pueden asignarse ArrayLists de subtipos de Animal al ArrayList del supertipo Animal.

>!El compilador detendrá la compilación.

>!La única cosa que puede pasarse como parámetro en un método cuyo argumento sea un ArrayList<Animal> será un ArrayList<Animal>

Page 15: Clase7 generics

Métodos con Generics (III)

public void addAnimal

(ArrayList<Animal> animals) {

animals.add(new Dog());

//a veces, vale...

}

>!Podríamos, sin embargo, hacer algo como lo que se ve arriba, lo cual compilará siempre y cuando lo que pasemos al método sea un ArrayList<Animal>.

Page 16: Clase7 generics

Métodos con Generics (IV)

>!Hay un mecanismo para “decirle” al compilador que podemos aceptar cualquier subtipo del argumento declarado en la parametrización, porque no vamos a agregar nada en la colección.

>!Dicho mecanismo se llama “Wildcard”.

public void addAnimal(List<?

extends Animal> animals)

Page 17: Clase7 generics

Métodos con Generics (V)

>!Con <? extends Animal> estamos diciendo “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

Page 18: Clase7 generics

Métodos con Generics (VI)

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í”.

>!Hay una forma de usar un wildcard y que nos sea permitido agregar elementos a la colección: la palabra “super”.

Page 19: Clase7 generics

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

}

Page 20: Clase7 generics

Pregunta

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

>!public void foo(List<Object> list)

{ }

>!¿En que se diferencian?

Page 21: Clase7 generics

Métodos con Generics (VIII)

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

>!Simplemente significa “cualquier tipo”.

>!Cualquier List podría asignarse al argumento.

>!Sin usar “super”, no podremos agregar nada a list.

Page 22: Clase7 generics

Métodos con Generics (IX)

public void foo(List<Object> list)

{}

>!Significa que el método solo puede tomar una List<Object>, no una lista parametrizada en algún subtipo de Object.

>!Sin embargo, podremos agregar cosas a la colección.

Page 23: Clase7 generics

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?

Page 24: Clase7 generics

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.

Page 25: Clase7 generics

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 específicamente el tipo “Animal”, y el método add a comportarse de la siguiente forma:

boolean add(Animal a)

Page 26: Clase7 generics

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

}

}

Page 27: Clase7 generics

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

}

}

Page 28: Clase7 generics

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

}

}

Page 29: Clase7 generics

Preguntas