genÉricos - dei.isep.ipp.ptnfreire/java - genéricos.pdf · herança em parâmetros de tipo...

23
Nelson Freire (ISEP–DEI-PPROG 2014/15) 1/23 GENÉRICOS (Livro Big Java, Late Objects – Capítulo 18) Paradigmas da Programação PPROG

Upload: donguyet

Post on 14-Dec-2018

244 views

Category:

Documents


0 download

TRANSCRIPT

Nelson Freire (ISEP–DEI-PPROG 2014/15) 1/23

GENÉRICOS

(Livro Big Java, Late Objects – Capítulo 18)

Paradigmas da Programação PPROG

Nelson Freire (ISEP–DEI-PPROG 2014/15) 2/23

Noção de Genérico

Interesse dos Genéricos

Tipos Parametrizados

Implementação

Classe Genérica

Método Genérico

Genéricos e Herança

Tipos Wildcard

Type Erasure

Contexto Estático

Bibliografia

Sumário Genéricos

Nelson Freire (ISEP–DEI-PPROG 2014/15) 3/23

Genéricos

Genéricos

Facilidade do Java

Java 5 (2004)

Atual

Java 8 (2014)

Permite construção

Tipos

Classes

Interfaces

Métodos

Construções designadas

Genéricas

Exemplos

Tipos genéricos

Classes genéricas

Interfaces genéricas

Métodos genéricos

Para funcionarem com objetos de vários tipos.

Noção de Genérico 1/2

Nelson Freire (ISEP–DEI-PPROG 2014/15) 4/23

Genéricos

Tipos e Métodos Genéricos

Têm um/mais parâmetros de tipo genérico // genérico = não concreto ; Ex: tipo E

Funcionam como variáveis // análogo aos parâmetros de métodos

Passagem de tipos … concretos // Ex: tipo String

Exemplos

Exemplo Declaração ... com tipo(s) genérico(s) Uso ... com vários tipos referência concretos

(Instâncias de tipo genérico)

Classe Genérica

public class ArrayList<E> ...

// E: parâmetro de tipo genérico

// <...> parêntesis angulares

// Variável

ArrayList<Figura> f

ArrayList<Pessoa> p

Interface Genérica

public interface Map<K,V>

// K e V: parâmetros de tipo genérico

Map<Integer,String>

Map<Departamento,

List<Empregado> >

Método Genérico

public static void shuffle(List<?> list)

// Classe Collections

// ?: parâmetro de tipo genérico = qualquer tipo

Collections.shuffle(f)

Collections.shuffle(p)

Noção de Genérico 2/2

Nelson Freire (ISEP–DEI-PPROG 2014/15) 5/23

Genéricos Interesse dos Genéricos 1/2

Programação mais segura

Mais robusta

Reduzir possibilidade de erros de execução

Devido a excessivos downcastings

Problema

Exemplo

// Contentor que permite guardar objetos de qualquer tipo

List figuras = new ArrayList(); // Elementos tipo Object

// Preenchimento do contentor

figuras.add( new Circulo() );

figuras.add( new Rectangulo() );

figuras.add( new Pessoa() ); // Adicionado objeto não Figura // Compilador aceita qualquer objeto

// Varrimento do contentor para mostrar áreas

for( Object obj : figuras )

System.out.println(((Figura) obj).area() );

Retangulo

area()

Circulo

area()

Figura

area()

Downcasting do objeto Pessoa provoca erro de execução

programação insegura

Nelson Freire (ISEP–DEI-PPROG 2014/15) 6/23

Genéricos Interesse dos Genéricos 2/2

Programação mais segura

Solução

Exemplo

Usando tipo genérico ArrayList<E>

// Contentor para guardar apenas objetos tipo Figura

List<Figura> figuras = new ArrayList(); // Elementos tipo Figura

// Preenchimento do contentor

figuras.add( new Circulo() );

figuras.add( new Rectangulo() );

figuras.add( new Pessoa() ); // ERRO de COMPILAÇÃO // Compilador só aceita objetos Figura

// Varrimento do contentor para mostrar áreas

for( Figura figura : figuras )

System.out.println( figura.area() );

Retangulo

area()

Circulo

area()

Figura

area() Não há downcasting

programação segura

Nelson Freire (ISEP–DEI-PPROG 2014/15) 7/23

Definição

Tipo obtido por instanciação do tipo genérico, substituindo os parâmetros de tipo genérico (ex: E) por tipos referência concretos (ex: String)

Exemplo

Interface List genérica

Tipos Concretos

Só tipos referência // tipos primitivos são ilegais

Tipo Parametrizado 1/2 Genéricos

(Parâmetro Tipo Genérico) (Parâmetro Tipo Concreto)

public interface List<E> … {

boolean add(E e);

}

public interface List<String> … {

boolean add(String e)

}

Tipo Genérico ( Ex: List<E> )

Tipo Parametrizado ( Ex: List<String> )

instanciado

substituído

Instanciação de Tipo Genérico

Nelson Freire (ISEP–DEI-PPROG 2014/15) 8/23

Pode ser usado

Declarações

Variáveis … locais/atributos

Parâmetros … de métodos/construtores

Tipos de retorno … de métodos

Tipo Parametrizado 2/2 Genéricos

public class DemoUsoTipoParametrizado {

private List<String> variavel;

public DemoUsoTipoParametrizado(List<String> lista){ … }

public void metodo1(List<Pessoa> lista){ … }

public List<String> metodo2(){

List<String> lista = new ArrayList();

}

}

Uso de Tipo Parametrizado

Nelson Freire (ISEP–DEI-PPROG 2014/15) 9/23

Parâmetros de Tipo Genérico (1/2)

Declaração

A seguir ao nome da classe Entre parêntesis angulares // < ... >

Especifica variáveis ... de instância

Uma por parâmetro de tipo genérico

Separadas por vírgulas

Nome de variáveis Pode ser qualquer Por convenção

Letra maiúscula

public class ArrayList<E> … {

public boolean add(E e){…}

}

Declaração de ArrayList Genérico

Nome de Variável Tipo Genérico

Significado

E Tipo de elemento de uma coleção

K Tipo key num mapa

V Tipo value num mapa

T Tipo genérico

S, U Tipos genéricos adicionais

Convenção Java

Genéricos Implementação de Classe Genérica 1/2

public class HashMap<K,V> … {

public V put(K key, V value){…}

}

Declaração de HashMap Genérico

Nelson Freire (ISEP–DEI-PPROG 2014/15) 10/23

Parâmetros de Tipo Genérico (2/2)

Usados

Só contexto de instância

Atributos de instância

Construtores

Tipos de Parâmetros

Corpo

Métodos de instância

Tipo de Parâmetro

Tipo de Retorno

Corpo

Classes internas

Não-estáticas

public class DemoClasseGenerica<T> {

private T variavel;

public DemoClasseGenerica(T obj){…}

public void metodo1(T obj){…}

public T metodo2(){…}

public T metodo3(T obj) {…}

private class classeInterna<T> … {…}

}

Exemplos de Uso de Parâmetro de Tipo Genérico

Genéricos Implementação de Classe Genérica 2/2

Parâmetro de tipo genérico no cabeçalho da classe

Ilegal em contexto estático

Variáveis estáticas

Métodos estáticos

Classe internas estáticas

Nelson Freire (ISEP–DEI-PPROG 2014/15) 11/23

Método Genérico

Método com um/mais parâmetros de tipo genérico

Implementação de Método Genérico

Genéricos Implementação de Método Genérico 1/2

Tipo de Classe Tipo de Método Parâmetros de Tipo Utilizáveis

Classe Genérica

Instância

Próprios

Cabeçalho da classe

Classe (estático) Próprios

Classe Não-Genérica

(sem parâmetros de tipo genérico)

Instância Próprios

Classe (estático) Próprios

Nelson Freire (ISEP–DEI-PPROG 2014/15) 12/23

Método Genérico de Classe Não-Genérica

Especifica tipo genérico próprio

Declaração

Antes do tipo de retorno

Exemplo

Método de classe

Invocação

Chamada convencional

Exemplo

Servicos.imprimir( nomes ); // String[] nomes

Não é preciso … indicar o tipo concreto do parâmetro de tipo genérico

Compilador deduz o tipo referência concreto // tipos primitivos ilegais

public class Servicos {

public static <T> void imprimir( T[] vetor ) {

}

}

Método que imprime qualquer tipo de vetor

Genéricos Implementação de Método Genérico 2/2

Nelson Freire (ISEP–DEI-PPROG 2014/15) 13/23

Herança em Parâmetros de Tipo Concreto

Não implica herança de classes parametrizadas

Exemplo

ArrayList<Figura> e ArrayList<Retangulo>

Não existe relação de herança entre arraylists

Retangulo é subtipo de Figura

Parâmetros de tipo estão relacionados por herança

Não é possível:

ArrayList<Retangulo> listaRetangulos = new ArrayList();

ArrayList<Figuras> listaFiguras = listaRetangulos; // Ilegal

Justificação

Caso contrário

Possível adicionar objetos de tipos não relacionados por herança a contentor

Exemplo

ArrayList<Figura> figuras = new ArrayList<>();

ArrayList<Retangulo> retangulos = new ArrayList<>();

...

figuras = retangulos; // Se fosse legal ...

figuras.add( new Circulo() ); // ... era possível adicionar um circulo ... aos retangulos

Genéricos

Retangulo

area()

Circulo

area()

Figura

area()

Genéricos e Herança 1/2

Nelson Freire (ISEP–DEI-PPROG 2014/15) 14/23

Implicações da Limitação

Exemplo

Tipo Parametrizado

MinhaLista<Figura>

Parâmetro List<E>

Permite Passagem

Listas de tipo E

Exemplo

new MinhaLista( new ArrayList<Figura>() )

Não Permite Passagem

Listas de subtipos/supertipos de E

Exemplo

new MinhaLista( new ArrayList<Circulo>() )

Ultrapassar Limitação

Tipos Wildcard

Genéricos

Retangulo

area()

Circulo

area()

Figura

area()

Genéricos e Herança 2/2

public class MinhaLista<E> {

public MinhaLista(List<E> lista){…}

}

Nelson Freire (ISEP–DEI-PPROG 2014/15) 15/23

Interesse

Restringir os tipos concretos passados através de parâmetros genéricos

Tipos Wildcard

Tipo Wildcard

Tipo desconhecido // não é preciso conhecer tipo específico

Exemplo

Construtor

Cria arraylist com elementos de c

Não precisa de saber ... tipo específico dos elementos de c

Permite elementos de c do tipo/subtipo de E

Genéricos

Nome Sintaxe Significado Obs

Wildcard com restrição inferior ? extends B Qualquer tipo/subtipo de B (limitado ao tipo e subtipos de

B)

? = qualquer tipo extends = tipo/subtipo B = classe/interface

Wildcard com restrição superior ? super B Qualquer tipo/supertipo de B super = tipo/supertipo

Wildcard sem restrições ? Qualquer tipo

Tipos Wildcard 1/5

public class ArrayList<E> … {

public ArrayList(Collection<? extends E> c) { … }

}

Nelson Freire (ISEP–DEI-PPROG 2014/15) 16/23

Wildcard com Restrição Inferior

Restrição inferior do tipo limitado ao tipo e subtipos

Exemplo

Construtor

Não precisa de saber tipo específico de elementos de c

Permite elementos de c do tipo/subtipo de E

Exemplo - ArrayList<Figura>

List<Figura> listaFiguras = new ArrayList(listaCirculos);

List<Circulo> listaCirculos = new ArrayList();

...

List<Figura> listaFiguras = new ArrayList(listaRetangulos);

List<Retangulo> listaRetangulos = new ArrayList();

Genéricos Tipos Wildcard 2/5

Nome Sintaxe Significado Obs

Wildcard com restrição inferior ? extends B Qualquer tipo/subtipo de B ? = qualquer tipo extends = subtipo B = classe/interface

public class ArrayList<E> … {

public ArrayList(Collection<? extends E> c) { … }

}

Retangulo Circulo

Figura

Nelson Freire (ISEP–DEI-PPROG 2014/15) 17/23

Wildcard com Restrição Superior

Restrição superior do tipo limitado ao tipo e supertipos

Exemplo

Método sort

Não precisa de saber tipo específico de objetos comparáveis

Permite objeto Comparator de tipo/supertipo de E

Exemplo

ArrayList<Circulo>

Comparator<Circulo>

Comparator<Figura>

Figura = supertipo de Circulo

Compara objetos tipo Figura Compara objetos tipo Circulo

Genéricos Tipos Wildcard 3/5

Nome Sintaxe Significado Obs

Wildcard com restrição superior ? super B Qualquer tipo/supertipo de B ? = qualquer tipo super = supertipo B = classe/interface

public class ArrayList<E> … {

public void sort(Comparator<? super E> c){ … }

}

Retangulo Circulo

Figura

Nelson Freire (ISEP–DEI-PPROG 2014/15) 18/23

Wildcard sem Restrição

Exemplo

Método removeAll

Remove todos elementos armazenados em c

Não precisa de saber tipo específico dos elementos de c

Permite elementos de c de qualquer tipo

Nota

Collection<Object>

Não equivalente a Collection<?>

Só permite coleção com elementos tipo Object

Genéricos Tipos Wildcard 4/5

public class ArrayList<E> … {

public boolean removeAll(Collection<?> c)

}

Nome Sintaxe Significado

Wildcard sem restrições ? Qualquer tipo

Nelson Freire (ISEP–DEI-PPROG 2014/15) 19/23

Tipos de Declarações de Restrições:

Um Tipo

Múltiplos Tipos

Declarações de Um Tipo

Exemplos

<?>

<? extends E>

<? super T>

Declarações de Múltiplos Tipos

Tipos ligados

Carater &

Exemplo

<? extends Comparable<E> & Measurable> // tipos de interfaces

Genéricos Tipos Wildcard 5/5

Nelson Freire (ISEP–DEI-PPROG 2014/15) 20/23

Máquina Virtual do Java (JVM)

Não trabalha com

Tipos genéricos

Métodos genéricos

Razão

Genéricos mais recentes que a JVM

Substitui parâmetros de tipo

Por tipos não parametrizados

Pelo tipo

Object // se não houver restrições

Da restrição

Exemplos

ArrayList<E>

E substituído por Object

ArrayList ... com elementos de tipo Object // resulta numa classe normal

<E extends Measurable>

E substituído por Measurable

Problema

Introduz limitações nos genéricos

Genéricos JVM Substitui Parâmetros de Tipo (Type Erasure) 1/2

Nelson Freire (ISEP–DEI-PPROG 2014/15) 21/23

Limitações

Impossível construir objetos de tipo genérico

Exemplos

new E() // Se E substituído por Objet new Object() – nem sempre desejável // Alternativa: ArrayList<E>

new E[20] // Array de tipo genérico

Construção de array de tipo genérico

Limitação pode ser ultrapassada

Usando técnica Reflection

JVM

Guarda objeto Class

Por cada classe carregada

Objeto Class tem

Informação sobre uma classe

Métodos para construir novos objetos dessa classe

Dado um array a de tipo genérico

Class objCA = a.getClass(); // obter objeto Class do array

Class objCE = objCA.getComponentType(); // obter objeto Class elementos

Object[] novoArray = Array.newInstance(objCE, tamanho); // criar array

Genéricos JVM Substitui Parâmetros de Tipo (Type Erasure) 2/2

Nelson Freire (ISEP–DEI-PPROG 2014/15) 22/23

Parâmetros de Tipo Genérico de uma Classe

São variáveis de instância

Não podem ser usados em contexto estático

Variáveis estáticas

Métodos estáticos // alternativa: adicionar parâmetros de tipo genérico

Classes internas estáticas // alternativa: adicionar parâmetros de tipo genérico

Contexto Estático Genéricos

Nelson Freire (ISEP–DEI-PPROG 2014/15) 23/23

Livro

Big Java, Late Objects

Cay S. Horstmann

2013

John Wiley & Sons

Tutorial

http://docs.oracle.com/javase/tutorial/java/generics/

Bibliografia Genéricos