Programação Java - Dei-Isep

Propaganda
Paradigmas da Programação
PPROG
GENÉRICOS
(Livro Big Java, Late Objects – Capítulo 18)
Nelson Freire (ISEP–DEI-PPROG 2014/15)
1/23
Genéricos
Sumário
 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
Nelson Freire (ISEP–DEI-PPROG 2014/15)
2/23
Noção de Genérico
Genéricos
1/2
 Genéricos
 Facilidade do Java
 Java 5 (2004)
 Atual
 Java 8 (2014)
 Permite construção
 Tipos
 Classes
 Interfaces
Para funcionarem com objetos de vários tipos.
 Métodos
 Construções designadas
 Genéricas
 Exemplos
 Tipos genéricos
 Classes genéricas
 Interfaces genéricas
 Métodos genéricos
Nelson Freire (ISEP–DEI-PPROG 2014/15)
3/23
Noção de Genérico
Genéricos
2/2
 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
Classe
Genérica
Declaração ... com tipo(s) genérico(s)
public class ArrayList<E> ...
// E: parâmetro de tipo genérico
Uso ... com vários tipos referência
concretos
(Instâncias de tipo genérico)
 ArrayList<Figura> f
 ArrayList<Pessoa> p
// <...> parêntesis angulares
// Variável
Interface
Genérica
public interface Map<K,V>
Método
Genérico
public static void shuffle(List<?> list)
// K e V: parâmetros de tipo genérico
// Classe Collections
 Map<Integer,String>
 Map<Departamento,
List<Empregado> >
 Collections.shuffle(f)
 Collections.shuffle(p)
// ?: parâmetro de tipo genérico = qualquer tipo
Nelson Freire (ISEP–DEI-PPROG 2014/15)
4/23
Interesse dos Genéricos
Genéricos
1/2
 Programação mais segura
 Mais robusta
Figura
area()
 Reduzir possibilidade de erros de execução
 Devido a excessivos downcastings
Retangulo
area()
 Problema
 Exemplo
Circulo
area()
// 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() );
Downcasting do objeto Pessoa provoca erro de execução

programação insegura
Nelson Freire (ISEP–DEI-PPROG 2014/15)
5/23
Interesse dos Genéricos
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() );
Não há downcasting

programação segura
Figura
area()
Retangulo
area()
Nelson Freire (ISEP–DEI-PPROG 2014/15)
Circulo
area()
6/23
Tipo Parametrizado
Genéricos
1/2
 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
Tipo Genérico
( Ex: List<E> )
instanciado
Tipo Parametrizado
( Ex: List<String> )
substituído
(Parâmetro Tipo Genérico)
public interface List<E> … {
(Parâmetro Tipo Concreto)
public interface List<String> … {
…
…
boolean add(E e);
boolean add(String e)
}
}
Instanciação de Tipo Genérico
 Tipos Concretos
 Só tipos referência
// tipos primitivos são ilegais
Nelson Freire (ISEP–DEI-PPROG 2014/15)
7/23
Tipo Parametrizado
Genéricos
2/2
 Pode ser usado
 Declarações
 Variáveis … locais/atributos
 Parâmetros … de métodos/construtores
 Tipos de retorno … de métodos
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)
8/23
Implementação de Classe Genérica
Genéricos
 Parâmetros de Tipo Genérico (1/2)
 Declaração
 A seguir ao nome da classe
 Entre parêntesis angulares // < ... >
1/2
public class ArrayList<E> … {
…
public boolean add(E e){…}
}
Declaração de ArrayList Genérico
 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
Nome de Variável
Tipo Genérico
public class HashMap<K,V> … {
…
public V put(K key, V value){…}
}
Declaração de HashMap 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
Nelson Freire (ISEP–DEI-PPROG 2014/15)
9/23
Implementação de Classe Genérica
Genéricos
2/2
 Parâmetros de Tipo Genérico (2/2)
 Usados
Parâmetro de tipo genérico no cabeçalho da classe
 Só contexto de instância
 Ilegal em contexto estático
 Atributos de instância
 Variáveis estáticas
 Construtores
 Métodos estáticos
 Classe internas estáticas
 Tipos de Parâmetros
 Corpo
 Métodos de instância
 Tipo de Parâmetro
 Tipo de Retorno
 Corpo
public class DemoClasseGenerica<T> {
…
private T variavel;
…
public DemoClasseGenerica(T obj){…}
…
public void metodo1(T obj){…}
 Classes internas
public T metodo2(){…}
public T metodo3(T obj) {…}
 Não-estáticas
…
private class classeInterna<T> … {…}
}
Exemplos de Uso de Parâmetro de Tipo Genérico
Nelson Freire (ISEP–DEI-PPROG 2014/15)
10/23
Implementação de Método Genérico
Genéricos
1/2
 Método Genérico
 Método com um/mais parâmetros de tipo genérico
 Implementação de Método Genérico
Tipo de Classe
Tipo de Método
Instância
Classe Genérica
Classe Não-Genérica
(sem parâmetros de tipo genérico)
Nelson Freire (ISEP–DEI-PPROG 2014/15)
Parâmetros de Tipo Utilizáveis
 Próprios
 Cabeçalho da classe
Classe (estático)
 Próprios
Instância
 Próprios
Classe (estático)
 Próprios
11/23
Implementação de Método Genérico
Genéricos
2/2
 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
public class Servicos {
…
public static <T> void
…
}
}
imprimir( T[] vetor ) {
Método que imprime qualquer tipo de vetor
 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
Nelson Freire (ISEP–DEI-PPROG 2014/15)
12/23
Genéricos e Herança
Genéricos
1/2
 Herança em Parâmetros de Tipo Concreto
 Não implica herança de classes parametrizadas
Figura
area()
 Exemplo

ArrayList<Figura> e ArrayList<Retangulo>
 Não existe relação de herança entre arraylists

Retangulo
area()
Circulo
area()
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
Nelson Freire (ISEP–DEI-PPROG 2014/15)
13/23
Genéricos e Herança
Genéricos
2/2
 Implicações da Limitação
 Exemplo
public class MinhaLista<E> {
…
public MinhaLista(List<E> lista){…}
…
}
 Tipo Parametrizado

MinhaLista<Figura>
Figura
area()
 Parâmetro List<E>
 Permite Passagem
 Listas de tipo E
Retangulo
area()
Circulo
area()
 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
Nelson Freire (ISEP–DEI-PPROG 2014/15)
14/23
Tipos Wildcard
Genéricos
1/5
 Interesse
 Restringir os tipos concretos passados através de parâmetros genéricos
 Tipos Wildcard
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
 Tipo Wildcard
 Tipo desconhecido
// não é preciso conhecer tipo específico
 Exemplo
public class ArrayList<E> … {
…
public ArrayList(Collection<? extends E> c) { … }
}
 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
Nelson Freire (ISEP–DEI-PPROG 2014/15)
15/23
Tipos Wildcard
Genéricos
2/5
Wildcard com Restrição Inferior
 Restrição inferior do tipo  limitado ao tipo e subtipos
Nome
Sintaxe
Wildcard com restrição inferior
? extends B
Significado
Qualquer tipo/subtipo de B
Obs
 ? = qualquer tipo
 extends = subtipo
 B = classe/interface
 Exemplo
public class ArrayList<E> … {
…
public ArrayList(Collection<? extends E> c) { … }
}
 Construtor
 Não precisa de saber tipo específico de elementos de c
 Permite elementos de c do tipo/subtipo de E
Figura
Retangulo
Circulo
 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();
Nelson Freire (ISEP–DEI-PPROG 2014/15)
16/23
Tipos Wildcard
Genéricos
3/5
 Wildcard com Restrição Superior
 Restrição superior do tipo  limitado ao tipo e supertipos
Nome
Sintaxe
Wildcard com restrição superior
? super B
Significado
Qualquer tipo/supertipo de B
Obs
 ? = qualquer tipo
 super = supertipo
 B = classe/interface
 Exemplo
public class ArrayList<E> … {
…
public void sort(Comparator<? super E> c){ … }
}
 Método sort
 Não precisa de saber tipo específico de objetos comparáveis
 Permite objeto Comparator de tipo/supertipo de E
 Exemplo

Figura
ArrayList<Circulo>
 Comparator<Circulo>

Retangulo
Circulo
Comparator<Figura>
 Figura = supertipo de Circulo
 Compara objetos tipo Figura  Compara objetos tipo Circulo
Nelson Freire (ISEP–DEI-PPROG 2014/15)
17/23
Tipos Wildcard
Genéricos
4/5
 Wildcard sem Restrição
Nome
Sintaxe
Significado
Wildcard sem restrições
?
Qualquer tipo
 Exemplo
public class ArrayList<E> … {
…
public boolean removeAll(Collection<?> c)
}
 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
Nelson Freire (ISEP–DEI-PPROG 2014/15)
18/23
Tipos Wildcard
Genéricos
5/5
 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>
Nelson Freire (ISEP–DEI-PPROG 2014/15)
// tipos de interfaces
19/23
JVM Substitui Parâmetros de Tipo (Type Erasure)
Genéricos
1/2
 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
Nelson Freire (ISEP–DEI-PPROG 2014/15)
20/23
Genéricos
JVM Substitui Parâmetros de Tipo (Type Erasure)
2/2
 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);
Nelson Freire (ISEP–DEI-PPROG 2014/15)
// criar array
21/23
Contexto Estático
Genéricos
 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
Nelson Freire (ISEP–DEI-PPROG 2014/15)
22/23
Genéricos
Bibliografia
 Livro
 Big Java, Late Objects
Cay S. Horstmann
2013
John Wiley & Sons
 Tutorial
 http://docs.oracle.com/javase/tutorial/java/generics/
Nelson Freire (ISEP–DEI-PPROG 2014/15)
23/23
Download