SlideShare una empresa de Scribd logo
1 de 95
Frameworks com Annotations e
       Reflection API
Fernando Camargo
Desenvolvedor Java EE e Android
Graduando do 4º ano de Engenharia De
 Computação pela UFG
Estuda e programa em Java desde 2009
Em estudo para a OCJP 6
Agenda

Frameworks
Annotations
Reflection
Framework Final: Serializador e desserializador
  XML-Objeto
Discussão sobre Frameworks
Discussão sobre Frameworks

         Hora de discutir!



  O que significa Framework?
Discussão sobre Frameworks

”Um framework, em desenvolvimento de
  software, é uma abstração que une códigos
  comuns entre vários projetos de software
  provendo uma funcionalidade genérica.”
Exemplo

Uma empresa de tecnologia, ao longo dos anos,
 foi desenvolvendo diversos sistemas para uso
 interno. Após anos, uma regra de negócio foi
 alterada para melhor posicionar a empresa no
 mercado. Essa regra era implementada em
 todos os sistemas internos. E agora, como
 alterá-la?
Framework e biblioteca

Biblioteca:
Classes independentes usadas para
 determinadas funções (utilitários) que são
 chamadas pelo cliente.
Framework:
Interconexão de classes que trabalham em
  conjunto para um fim comum às várias
  aplicações. O cliente insere código específico
  que será chamado pelo código geral do
  Framework.
Exemplo

Depois de um projeto de 3 anos, um grupo de
 programadores pega um projeto parecido e
 com grande nível de complexidade. Vendo que
 poderiam reutilizar código, eles copiam e colam
 o que pode ser reusado nesse novo projeto.
 Depois de 1 ano, eles descobrem que há uma
 falha grave de segurança no primeiro projeto,
 em código comum ao 2º. Como resolver o
 problema dos dois? Se esse código reusável
 estivesse em um único lugar, seria mais fácil
 ou difícil?
Framework

Acima de tudo, reusável
Atender as novas classes criadas, fazendo
 coisas específicas.


Como ser reusável e ser específico ao mesmo
 tempo? Não possuimos nada sobre as classes
 que serão criadas no futuro!
Prever o Futuro (?)

Existem algumas formas de prevermos o futuro,
 nesse caso.
Interfaces
Classes abstratas
Metadados
Interfaces e Classes Abstratas

Através delas, podemos prever o que poderá ser
 feito em tempo de compilação, mas obrigamos
 o cliente a assinar contratos (interfaces),
 implementando métodos que podem não ser
 de seu interesse ou tiramos sua oportunidade
 de usar herança, obrigando-o a fazer sua
 classe herdar de uma classe abstrata.
Interfaces e Classes Abstratas

Interfaces e classes abstratas podem compor um
  framework?
Sim.
Então por que não usar apenas interfaces e
 classes abstratas?
Plug and play
Alternativa

Alternativa para deixar as classes de negócios
  simples e independentes:
Metadados: XML e Annotations
Interpretação e execução: Reflection API
Metadados

Dados que descrevem dados
Mostra ao framework o que você deseja
Deixa as classes limpas para implementar
 apenas o necessário
Desvantagens: não geram erros de compilação,
 já que as verificações só poderão ser feitas em
 tempo de execução.
Metadados (XML)

Pode ser criado para configurar um framework e
 lhe mostrar a direção correta.
Vantagem: pode ser modificado sem necessitar
 recompilação.
Desvantagem: aplicações grandes e complexas
 podem gerar arquivos XML gigantes e difíceis
 de serem lidos.
Metadados (Annotations)

São anotações que descrevem classes,
 métodos, propriedades e parâmetros.
São anotadas em sua própria classe, ao invés de
 acumuladas em um XML.
Facilita a leitura e o ententimento de outros
 programadores
Desvantagens: necessita recompilação do
 código, quando alterado.
Reflection

Reflection:
É a habilidade de um programa observar e
 modificar sua própria estrutura em tempo de
 execução.
Java provê essa habilidade através da Reflection
  API
Interpretando os metadados

Com Reflection, podemos interpretar os
 metadados que descrevem uma classe e
 acessar, modificar e chamar propriedades,
 métodos, e toda a estrutura da classe.
O código interpreta os metadados e as classes
 descritas em tempo de execução.
Frameworks famosos

Spring (XML, Annotations e Reflection)
EJB 3 (XML, Annotations e Reflection)
JSF (XML, Annotations e Reflection)
Hibernate (XML, Annotations e Reflections)
JUnit (Classes Abstratas → Annotations)
Annotations
Introdução às Annotations

Criadas na versão 1.5 do Java
Têm papel de metadado
Podem descrever:
Classe
Construtor
Método
Parâmetro
Variável local e de instância
Annotation
Annotations pré-existentes

@Override
@SuppressWarnings
@Deprecated
@Rentention
@Target
@Documented
@Inherited
@Override

Informa o compilador que determinado método
  está sendo sobrescrito.
Caso anote um método que não é herdado,
 ocorrerá um erro de compilação.



                 Exemplo 1
@SuppressWarnings

Informa o compilador que determinado(s)
  warning(s) são de seu conhecimento e não
  devem ser emitidos pelo compilador.




                 Exemplo 2
@Deprecated

Avisa aos possíveis usuários da API e o
 compilador que aquele método não deveria ser
 mais usado, pois há alternativas melhores.




                 Exemplo 3
As demais

@Rentention, @Target, @Documented e
 @Inherited são meta-annotations. Usadas para
 descrever outras annotations e será mostrado
 em breve.
Annotations criadas por
       Frameworks famosos
@Entity: Descreve uma classe como uma
 unidade a ser persistida.
@ManagedBean: Descreve que uma classe
 deve ser gerenciada pela JSF.
@Named: Nomeia uma classe para ser usada
 em CDI.
@Service: Descreve uma classe como um
 serviço.
@Inject: Descreve que determinada instância ou
 parâmetro deve ser injetada.
Criando nossas Annotations

Uma Annotation é declarada da seguinte forma:


public @interface Annotation{
    String parametro();
}
Classificações de Annotations

Podemos separar as Annotations em várias
 classificações:
Quanto a quantidade de parâmetros
Quanto ao seu alvo
Quanto a sua retenção
Documentadas ou não
Annotation de nenhum parâmetro




           Exemplo 4
Annotation de único parâmetro




           Exemplo 5
Annotation de múltiplos
     parâmetros




        Exemplo 6
Tipos de Parâmetros

Tipos primitivos
String
Class
Enum
Array dos tipos acima


                   Exemplo 7
Alvos das Annotations

As annotations, quando criadas, podem definir
 em quais lugares podem ser aplicadas.
A meta-annotation @Target indica quais
 elementos de código para os quais uma
 annotation é aplicavel.
Esses alvos são: Tipo, Propriedade, Método,
 Parâmetro, Construtor, Variável Local e
 Annotation.
                  Exemplo 8
Retenção das Annotations

As annotations também podem definer até que
 ponto elas devem ser consideradas.
Através da meta-annotation @Retention,
 podemos definir que uma annotation deva ser
 considerada. Temos três opções:
Apenas no código fonte.
Durante a compilação
Durante a execução (usada no Reflection)
                  Exemplo 9
Documentação da Annotation

As annotations podem ou não aparecer no
 JavaDoc do projeto. Para habilitar isso, apenas
 anote a Annotation com:
@Documented




Lembre-se: Um framework não documentado é
 inútil!
A meta-annotation @Inherited

Indica que a annotation criada no momento será
  herdada em todas as subclasses.
Ou seja, quando buscarmos se uma determinada
 classe tem essa annotation, a encontraremos
 caso uma superclasse a tenha.



                 Exemplo 10
Reflection

Examinar o programa por sua estrutura e dados
Tomar decisões usando os resultados do exame
Mudar o comportamento, estrutura ou dados do
 programa baseado nas decisões
O trabalho de um programador? Ou pode ser
 feito pelo próprio programa?
Reflection

Vamos ver agora um exemplo simples desses
 três passo.




                Exemplo 11
Reflection - Introspection

Reflection é a habilidade de um programa fazer
 os 3 itens ditos anteriormente.
Para fazer um auto-exame, é necessário que o
 programa tenha uma representação de si
 mesmo, o que chamamos metadados. Na
 orientação a objetos, metadata é organizada
 em objetos, o que nos dá metaobjetos. A auto-
 examinação de um programa em tempo de
 execução é chamada introspection
 (introspecção).
Reflection – Mudança de
          comportamento
Existem três técnicas para fazer a mudança de
 comportamento em um programa:
Modificação direta do metaobjeto
Operações usando os metadados
Intercessão (interceder em várias fases de
  execução do programa)
Java nos traz a Reflection API várias operações
  usando os metadados e algumas capacidades
  de intercessão, mas não nos permite modificar
  o metaobjeto.
Discussão

Imagine a situação em que um projeto tenha
  várias classes de diferentes bibliotecas que
  compoem a interface gráfica. Algumas dessas
  bibliotecas não podem ser modificadas.Todas
  elas possuem um método setColor, que recebe
  um objeto do tipo Color, mas elas não
  implementam nenhuma interface em comum
  nem extendem uma superclasse.Queremos
  chamar esse método para qualquer desses
  componentes, o que faremos?
Melhor solução para a Discussão

A melhor solução para esse problema é um
 método que recebe um Object e faz uso de
 Reflection para encontrar um método setColor
 que receba um parâmetro Color e o chamar.



                 Exemplo 12
Class

O objeto do tipo Class é a base da introspecção.
 Ele é o metaobjeto que representa determinada
 classe.
Através dele acessamos:
Campos
Métodos
Árvore hierárquica (superclasses e subclasses)
Construtores
Annotations
Obtendo um objeto Class

Temos três formas de obter o objeto Class.
getClass(): Herdade de Object. Nos retorna, em
 tempo de execução, o objeto Class de uma
 determinada instância.
.class: É chamado usando o nome da classe
  seguido por '.class'. Devemos decidir em tempo
  de compilação qual classe queremos.
Class.forName(”className”): Retorna o objeto
 Class a partir do nome da classe.
Obtendo um método

Um método tem por assinatura seu nome e seus
 parâmetros. Podemos obtê-los da seguinte
 forma:
getMethod: retorna um método público com dada
 assinatura, independente se é herdado ou
 declarado na classe.
getDeclaredMethod: retorna um método
 declarado na classe, independente de sua
 visibilidade, a partir de sua assinatura.
Assinatura de um método

Ambos getMethod e getDeclaredMethod
 recebem os mesmos parâmetros:
getMethod(String nomeDoMetodo,
                Class... parametros);
Os parâmetros são um var-args de Class que
 representam esses parâmetros.
Listando métodos

Podemos listar todos os métodos de uma classe
 através dos métodos:
getMethods(): retorna um array de Method de
 visibilidade pública, declarados ou herdados.
getDeclaredMethods(): retorna um array de
 Method declarados na classe, independente da
 visibilidade.
Discussão

Vimos que passamos um var-args de Class para
  encontrarmos um método.


Como encontrariamos um método que recebe
 como parâmetro uma variável primitiva, uma
 interface e/ou um array?
Representando tipos através de
           Class
Em Java, devido ao problema da discussão,
 todos os tipos são representados com um
 objeto Class. Isso inclui as Interfaces, os tipos
 primitivos e os arrays.
Esses objetos Class não podem fazer todas as
 coisas que outras podem. Você não pode criar
 uma nova instância de um primitivo ou uma
 interface.
Essas representações são necessária para fazer
 a introspecção.
Representando tipos através de
           Class
Após obtermos o objeto Class, podemos testar
 se ele representa um array, um primitivo ou
 uma interface através dos métodos:
isArray()
isPrimitive()
isInterface()
Veremos agora como Java representa cada um
 desses tipos usando objetos Class.
Representando tipos primitivos

Embora tipos primitivos não sejam objetos, Java
 usa objetos Class para representar todos os 8
 tipos primitivos. Os primitivos são
 representados usando o literal 'class' após o
 nome do primitivo. Assim, representamos:
int.class, float.class, double.class, short.class,
  long.class, char.class, boolean.class, byte.class
Também precisamos de uma representação para
 void, que é representado por void.class.
Representando interfaces

Java também introduz um objeto Class para
  representar cada Interface declarada. Esses
  objetos podem ser usados para indicar
  parâmetros do tipo de uma interface.
Obtemos o objeto Class que representa uma
 interface através do literal 'class'. Um exemplo
 seria a interface Collection, sendo
 representada por Collection.class.
Representando arrays

Arrays, em Java, são objetos, mas suas classes
 são criadas pela JVM em tempo de execução.
 Seus objetos Class também são obtidos
 através do literal 'class'. Por exemplo, um array
 de uma dimensão de Object é representado
 por Object[].class.
Podemos descobrir qual o componente de um
 array através de getComponentType(), que
 retornaria um objeto Class de Object para o
 exemplo acima.
Exemplo: fazendo introspecção
       na classe Vector
Vamos fazer introspecção para pegar os
 seguintes métodos da classe Vector:
addAll(Collection c)
copyInto(Object[] anArray)
get(int index)


                   Exemplo 13
O objeto Method

Representa um método de determinada classe
 que tenha determinada assinatura (nome +
 parâmetros).
Provê imformações sobre um método, como seu
 nome, os tipos de seus parâmetros, o tipo de
 seu retorno e exceções. Também dá a
 habilidade de invocá-lo em uma instância da
 classe que o declara.
Invocação dinâmica (1)

Habilita um programa a chamar um método de
 um objeto em tempo de execução sem
 especificá-lo em tempo de compilação.
Object invoke(Object target, Object...
 parameters);
Target é o objeto que terá seu método chamada.
 Parâmetros (var-args) são os parâmetros que o
 método invocado espera. O método invoke
 retorna um Object, o retorno do método
 invocado.
Invocação dinâmica (2)

O primeiro parâmetro, target, será
 desconsiderado em um método static, então é
 legal passar null. Também é legal passar null
 ou um nada em um método sem parâmetros.
Os parâmetros são passados como Object, o
 que significa que são passados os Wrappers
 ao invés dos primitivos (Integer – int). O
 mesmo vale para o retorno, que retorna um
 Object.
Um método de retorno void terá um retorno null
 no método invoke.
Invocação dinâmica (3)

IllegalArgumentoException será lançada quando
   o target não suportar o método ou quando os
   parâmetros estiverem incorretos.
Qualquer exceção lançada dentro do método
 invocado lançará uma
 InvocationTargetException.


                 Exemplo 14
Discussão

Temos o método getMethod para acessar
 métodos públicos (declarados e herdados) e
 temos getDeclaredMethod para acessar
 métodos declarados de qualquer visibilidade.
Como podemos acessar um método protected de
 uma superclasse?


                 Exemplo 15
Árvore de hierarquia

Podemos ter acesso à informações da árvore de
 hierarquia de uma classe através dos seguintes
 métodos:
Class[] getInterfaces()
Class getSuperclass()
boolean isAssignableFrom(Class cls): Verificada
 se cls é uma subclasse.
boolean isInstance(Object obj): Versão de
 Reflection de instanteof.
O objeto Field

Representa um campo (variável de instância) de
 determinada classe. É identificado pela classe
 o qual pertence e pelo nome.
Através dele, obtemos informações sobre o tipo,
 o nome, os modificador e até o valor do campo
 de uma instância. Podemos usá-lo para pegar
 e modificar o valor de um campo.
Acesso um objeto Field (1)

Assim como fizemos com o objeto Method, será
 forma com o objeto Field.
getField(String nome): retorna um campo público
 que tenha esse nome.
getDeclaredField(String nome): retorna um
 campo de qualquer visibilidade declarado na
 classe.
getFields(): retorna todos os campos públicos.
getDeclaredFields():retorna todos os campos
 declarados.
Acesso a um objeto Field (2)

Para acessar todos os campos declarados e
 herdados independente de visibilidade,
 devemos percorrer a árvore hierarquica em
 busca dos campos declarados nela.
Quando uma busca por um campo não o
 encontra, é lançada a NoSuchFieldException.



                 Exemplo 16
Modificadores

Class, Method e Field possuem modificadores.
 Entre seus possíveis modificadores, podemos
 citar: public, private, protected, static, final,
 abstract, etc.
Para termos acesso a esses modificadores,
 usamos getModifiers(), que retorna um número
 inteiro (vetor de bits). Para usarmos esse vetor
 de bits, usamos a classe Modifier para
 interpretá-lo.


                   Exemplo 17
Valor de um Field (1)

Podemos acessar o valor do campo de um
 objeto e também modificá-lo através de
 Reflection.
get(Object target): Retorna o valor do campo na
 instância target.
set(Object target, Object value): Ajusta o campo,
  na instância target, para o novo valor 'value'.
Em ambos os casos, primitivos são usados
 através de seus Wrappers (int – Integer)
Valor de um Field (2)

Também há um método específico para cada
 primitivo/wrapper. Porém, só devem ser usados
 caso tenha certeza do tipo do campo, ou
 lançaram IllegalArgumentException.
getBoolean / setBoolean
getInt / setInt
…


                  Exemplo 18
Acessibilidade (1)

Como visto no exemplo anterior, ao tentar
 acessar campos não públicos, é lançada uma
 IllegalAccessException. O mesmo acontece
 com métodos.
Isso acontece porque, em tempo de execução,
  há uma checagem de acesso na invocação de
  métodos e acesso do valor de campos.
Acessibilidade (2)

Podemos contornar isso desabilitando a
 verificação de acessibilidade em tempo de
 execução. Fazemos isso usando:
setAccessible(boolean param): Se true, torna o
  método/campo acessível via Reflection. Se
  false, torna inacessível.
boolean isAccessible(): Verifica a situação atual
 do método/campo.


                   Exemplo 19
Desvantagens na acessibilidade

Quebra o encapsulamento dos objetos.
Não é uma operação ”leve”.
Pode ser desabilitada em algumas JVMs.


Devemos usar essa operação apenas em caso
 estritamente necessários. Ao contrário,
 devemos priorizar por chamar apenas métodos
 públicos e usar os getters e setters de
 determinado campo.
Campo do tipo Array (1)

Array é um tipo de objeto diferente que merece
 um tratamento especial. Para isso, o Java
 provê a classe Array como um facilitador nas
 operações com Array's em Reflection. Ele
 possui os seguintes métodos:
getLenght(Object array): Retorna o tamanho do
 array.
get(Object array, int i): Retorna o i-ésimo
 elemento do array.
set(Object array, int i, Object valor): Ajusta o
  valor do i-ésimo elemento do array.
Campo do tipo Array (2)

newInstance(Class tipo, int length): Cria um novo
 array do tipo especificado com o tamanho
 especificado.
Também temos outros métodos que devem ser
 consultados na API.


                  Exemplo 20
Reflection e Generics (1)

Generics são usados em duas situações:
Declarar uma classe/interface como
 parametrizada.
Usar uma classe parametrizada.
Usamos constantemente classes parametrizadas
 desde o Java 5. Um grande uso está nas
 collections, como List, Vector, Map, etc. Essa
 parametrização nos permite criar uma lista de
 String's ao invés de uma lista de Object's.
Reflection e Generics (2)

Em tempo de execução, essa parametrização é
 apagada da classe, já que podem haver várias
 instâncias com parâmetros diferentes. Mas
 essa informação fica disponível nos Method's,
 Field's, nas interfaces e superclasses
 parametrizadas através de Reflection.
Assim como é importante saber o tipo dos
 componentes de um Array, também é
 importante saber o tipo dos objetos guardados
 em uma Collection nas nossas introspecções.
Reflection e Generics (3)

É importante saber que Class implementa a
 interface Type, pois trabalharemos com essa
 interface e também com ParameterizedType.
Através de um Method ou um Field, teremos
 acesso a um ParameterizedType (que pode
 possuir mais de um tipo parametrizado).
 Através disso, acessamos a lista de Type's,
 que podemos dar um cast para Class e
 continuar nossa introspecção.
GenericReturnType

Um método pode retornar uma classe/interface
 parametrizada. É importante sabermos qual o
 tipo dessa parametrização.
Usamos o método:
Type getGenericReturnType()
Esse método retorna um Type. Então podemos
 testar usando 'instanceof' se esse tipo se trata
 de um ParameterizedType. Caso seja,
 acessamos os tipos como foi descrito.
                  Exemplo 21
Reflection e Generics (4)

É importante saber que todos os métodos
 ”getGeneric[...]()” retorna um Type, que pode
 ser um ParameterizedType.
Esses métodos estão presentes em Method:
getGenericReturnType(): Usado para seu
 retorno.
getGenericParameterTypes(): Retorna um array
 de Type dos parâmetros.
getGenericExceptionTypes(): Funciona da
 mesma forma para Exceptions.
Reflection e Generics (5)

Em Field:
getGenericType(): Usado para verificar o tipo do
 campo.
Em Class:
getGenericInterfaces(): Retorna os tipos das
 interfaces implementadas pela classe.
getGenericSuperclass(): Retorna o tipo da
 superclasse.
Constructor (1)

Uma classe possui de 1 a N construtores. É
 através deles que um objeto é construído.
Acessando um metaobjeto Constructor, podemos
 construir um objeto de uma determinada
 classe.
Podemos obter um Constructor da seguinte
 forma:
Constructor getConstructor(Class...
 tiposParametros): Retorna um Constructor para
 os tipos de parâmetro especificados.
Constructor (2)

Constructor[] getConstructors(): Retorna todos os
 construtores da classe.
Quando um construtor não é encontrado para
 determinados tipos de parâmetros, é lançada
 uma NoSuchMethodException, assim como
 acontece quando um método não é
 encontrado.
Também acessamos os tipos de seus
 parâmetros através de:
getParameterTypes(): Retorna as classes que
 representam os tipos dos parâmetros.
Constructor (3)

Possuindo uma instância do tipo Constructor,
 podemos criar uma nova instância da classe a
 qual ele pertence.
Criamos uma nova instância da classe da
 seguinte forma:
Object newInstance(Object... parametros): Cria
 uma nova instância da classe usando os
 parâmetros passados.


                  Exemplo 22
Constructor (4)

As exceções lançadas e a acessibilidade do
 construtor se assemelha ao de um método.
 Também é válido torná-lo acessível através de
 setAccessible(boolean).
Podemos parametrizá-lo com a classe que será
 construíza, caso saibamos qual é. Assim, ao
 invés de retornar um Object, ele retornará a
 classe parametrizada.
JavaBeans e Reflection (1)

JavaBeans são POJOS (Plain Old Java Objects)
  que serem um padrão de encapsulamento dos
  campos.
Entre vários outras coisas especificadas, temos
 que os campos devem ser privados com
 métodos de acesso (get e set).
Como vimos, devemos evitar mudar a
 acessibilidade dos campos com Reflection, por
 ser um processo pesado e romper seu
 encapsulamento.
JavaBeans e Reflection (2)

Padrão de métodos de acesso para campos
 privados:
Propriedade: T xyz
public T getXyz()
public void setXyz(T novoValor)
Propriedade: boolean xyz
public boolean isXyz()
public void setXyz(boolean novoValor)
JavaBeans e Reflection (3)

Devemos, sempre que possível, recorrer aos
 métodos de acesso para acessar campos
 privados. Temos duas alternativas para isso:
Tratar o nome do campo para se chegar o nome
  correto do método de acesso.
Utilizar as classes do pacote java.beans.
Vamos abordar a primeira alternativa por ser
 mais simples. O pacote java.beans poderá ser
 estudado depois.
                  Exemplo 23
Annotations e Reflection (1)

As Annotations especificadas a perdurarem até o
 tempo de execução poderão ser acessadas via
 Reflection.
Assim como classes, interfaces e primitivos, as
 Annotations também tem uma representação
 através de uma Class.
Uma instância com os valores definidos na
 anotação é representado pelo tipo Annotation.
 Podemos usar sua representação de Class
 para alcançar sua representação Annotation.
Annotations e Reflection (2)

Classes, interfaces, métodos, parâmetros,
 construtores e campos podem ser anotados.
 Dessa forma, todos possuem os métodos:
Annotation getAnnotation(Class cls): Retorna
 uma instância do tipo da Annotation. Podemos
 dar um downcast para nossa annotation e usá-
 la para acessar os valores definidos onde foi
 anotada.
Annotations e Reflection (3)

Annotation[] getAnnotations(): Retorna um array
 com todas as annotations definidas e herdadas
 no elemento.
Annotation[] getDeclaredAnnotations(): Retorna
 um array com apenas as annotations definidas
 no elemento. As herdadas (@Inherited) são
 ignoradas.


                 Exemplo 24
Por onde seguir

Antes de apresentar o Framework final, feito com
 o conteúdo apresentado, segue uma lista do
 que falta estudar:
Pacote java.beans.
Proxy (interceptação de métodos)
Questões de performance
Classloader
Geração de código
Framework Final (1)

A proposta de framework a ser implementada é a
 seguinte:
Framework reponsável por gerenciar a
  sincronização de dados entre diferentes
  plataformas. Essa sincronização precisará de
  trocas de mensagens, que irão conter uma
  serialização dos objetos na forma de XML.
As diferentes plataformas que receberem as
 mensagens terão um deserializador que
 transformará o XML de volta para um objeto.
Framework Final (2)

Usando Annotations e Reflection, nos
 limitaremos a implementar apenas o
 serializador e o deserializador de Objeto-XML.
As classes dos objetos serão anotadas com
 algumas configurações para a serialização.
Devemos criar esses Annotations e os métodos
 de serialização e deserialização.
Especificando os metadados

Os metadados serão compostos das seguintes
 annotations:
@XML: Marca que uma classe pode ser
 serializada e deserializada em XML. Também
 especifica como será a serialização dos
 campos ou de um campo campo específico
@Transient: Marca que um campo não deve ser
 serializado
@ServerId: Marca um campo como sendo o
 identificador do objeto no servidor
Eagle Sync

A proposta do Framework está implementada
 com código fonte livre sobre licença Apache
 2.0, o que dá o direito de qualquer pessoa usar
 o código da forma que quiser.
Para ver ou contribuir com o projeto, acesse:
code.google.com/p/eagle-sync/
Referências

FORMAN, I. R.; FORMAN, N. Java Reflection in
 Action. Manning, 2006.
<http://www.developer.com/java/other/article.php/
 3556176/An-Introduction-to-Java-
 Annotations.htm>
<http://tutorials.jenkov.com/java-
 reflection/index.html>
<http://www.dsc.ufcg.edu.br/~jacques/cursos/ma
 p/html/frame/oque.htm>
Contatos

Email: fernando.camargo.ti@gmail.com
Twitter: @fernandosst
Facebook: www.facebook.com/fernandosst
LinkedIn: br.linkedin.com/pub/fernando-camargo/
  26/21/286
Blog: fernandocamargoti.blogspot.com

Más contenido relacionado

La actualidad más candente

Curso de Java (Parte 2)
 Curso de Java (Parte 2) Curso de Java (Parte 2)
Curso de Java (Parte 2)Mario Sergio
 
Linguagem de Programação Java para Iniciantes
Linguagem de Programação Java para IniciantesLinguagem de Programação Java para Iniciantes
Linguagem de Programação Java para IniciantesOziel Moreira Neto
 
Unidade iii aula 02 - introdução ao java
Unidade iii   aula 02 - introdução ao javaUnidade iii   aula 02 - introdução ao java
Unidade iii aula 02 - introdução ao javaNécio de Lima Veras
 
Curso de Java (Parte 1)
Curso de Java (Parte 1)Curso de Java (Parte 1)
Curso de Java (Parte 1)Mario Sergio
 
Padroes De Projeto
Padroes De ProjetoPadroes De Projeto
Padroes De Projetoejdn1
 
lista de exercícios de estrutura de dados Básico primeira prova
lista de exercícios de estrutura de dados Básico primeira prova lista de exercícios de estrutura de dados Básico primeira prova
lista de exercícios de estrutura de dados Básico primeira prova Rogério Cardoso
 
Aula de Introdução - JAVA
Aula de Introdução  - JAVAAula de Introdução  - JAVA
Aula de Introdução - JAVAMoises Omena
 
Programação Orientada a Objetos com Java
Programação Orientada a Objetos com JavaProgramação Orientada a Objetos com Java
Programação Orientada a Objetos com JavaÁlvaro Farias Pinheiro
 
Introdução ao JAVA (linguagem de programação WEB)
Introdução ao JAVA (linguagem de programação WEB)Introdução ao JAVA (linguagem de programação WEB)
Introdução ao JAVA (linguagem de programação WEB)Luis Borges Gouveia
 
Java 10 Classes Abstratas Interfaces
Java 10 Classes Abstratas InterfacesJava 10 Classes Abstratas Interfaces
Java 10 Classes Abstratas InterfacesRegis Magalhães
 
Introdução a programação Orientada a Objeto
Introdução a programação Orientada a ObjetoIntrodução a programação Orientada a Objeto
Introdução a programação Orientada a ObjetoMarconi Rodrigues
 
Curso de OO com C# - Parte 01 - Orientação a objetos
Curso de OO com C# - Parte 01 - Orientação a objetosCurso de OO com C# - Parte 01 - Orientação a objetos
Curso de OO com C# - Parte 01 - Orientação a objetosLeonardo Melo Santos
 

La actualidad más candente (20)

Curso de Java (Parte 2)
 Curso de Java (Parte 2) Curso de Java (Parte 2)
Curso de Java (Parte 2)
 
03 fundamentos java
03 fundamentos java03 fundamentos java
03 fundamentos java
 
Linguagem de Programação Java para Iniciantes
Linguagem de Programação Java para IniciantesLinguagem de Programação Java para Iniciantes
Linguagem de Programação Java para Iniciantes
 
Unidade iii aula 02 - introdução ao java
Unidade iii   aula 02 - introdução ao javaUnidade iii   aula 02 - introdução ao java
Unidade iii aula 02 - introdução ao java
 
1707331929 ltp iv java original
1707331929 ltp iv   java original1707331929 ltp iv   java original
1707331929 ltp iv java original
 
Java
JavaJava
Java
 
Teste Driven Development
Teste Driven DevelopmentTeste Driven Development
Teste Driven Development
 
Curso de Java (Parte 1)
Curso de Java (Parte 1)Curso de Java (Parte 1)
Curso de Java (Parte 1)
 
Design Patterns
Design PatternsDesign Patterns
Design Patterns
 
Padroes De Projeto
Padroes De ProjetoPadroes De Projeto
Padroes De Projeto
 
lista de exercícios de estrutura de dados Básico primeira prova
lista de exercícios de estrutura de dados Básico primeira prova lista de exercícios de estrutura de dados Básico primeira prova
lista de exercícios de estrutura de dados Básico primeira prova
 
Aula de Introdução - JAVA
Aula de Introdução  - JAVAAula de Introdução  - JAVA
Aula de Introdução - JAVA
 
Programação Orientada a Objetos com Java
Programação Orientada a Objetos com JavaProgramação Orientada a Objetos com Java
Programação Orientada a Objetos com Java
 
Introdução ao JAVA (linguagem de programação WEB)
Introdução ao JAVA (linguagem de programação WEB)Introdução ao JAVA (linguagem de programação WEB)
Introdução ao JAVA (linguagem de programação WEB)
 
Java 10 Classes Abstratas Interfaces
Java 10 Classes Abstratas InterfacesJava 10 Classes Abstratas Interfaces
Java 10 Classes Abstratas Interfaces
 
Introdução a programação Orientada a Objeto
Introdução a programação Orientada a ObjetoIntrodução a programação Orientada a Objeto
Introdução a programação Orientada a Objeto
 
Introdução ao Java
Introdução ao JavaIntrodução ao Java
Introdução ao Java
 
01 java fundamentos
01 java fundamentos01 java fundamentos
01 java fundamentos
 
Curso de OO com C# - Parte 01 - Orientação a objetos
Curso de OO com C# - Parte 01 - Orientação a objetosCurso de OO com C# - Parte 01 - Orientação a objetos
Curso de OO com C# - Parte 01 - Orientação a objetos
 
Programação Orientada a Objetos - 001
Programação Orientada a Objetos - 001Programação Orientada a Objetos - 001
Programação Orientada a Objetos - 001
 

Destacado

Boas práticas no desenvolvimento de uma RESTful API
Boas práticas no desenvolvimento de uma RESTful APIBoas práticas no desenvolvimento de uma RESTful API
Boas práticas no desenvolvimento de uma RESTful APIFernando Camargo
 
Banco de dados no Android com Couchbase Lite
Banco de dados no Android com Couchbase LiteBanco de dados no Android com Couchbase Lite
Banco de dados no Android com Couchbase LiteFernando Camargo
 
JoinCommunity 2 - Projetando um novo app usando user centered design
JoinCommunity 2 - Projetando um novo app usando user centered designJoinCommunity 2 - Projetando um novo app usando user centered design
JoinCommunity 2 - Projetando um novo app usando user centered designFernando Camargo
 
Boas práticas no desenvolvimento de uma RESTful API
Boas práticas no desenvolvimento de uma RESTful APIBoas práticas no desenvolvimento de uma RESTful API
Boas práticas no desenvolvimento de uma RESTful APIFernando Camargo
 
Spring Framework - Validation
Spring Framework - ValidationSpring Framework - Validation
Spring Framework - ValidationDzmitry Naskou
 
Spring Framework - Data Access
Spring Framework - Data AccessSpring Framework - Data Access
Spring Framework - Data AccessDzmitry Naskou
 
Spring Framework - Expression Language
Spring Framework - Expression LanguageSpring Framework - Expression Language
Spring Framework - Expression LanguageDzmitry Naskou
 
Spring Framework - Web Flow
Spring Framework - Web FlowSpring Framework - Web Flow
Spring Framework - Web FlowDzmitry Naskou
 
Spring Framework - MVC
Spring Framework - MVCSpring Framework - MVC
Spring Framework - MVCDzmitry Naskou
 
Spring Framework - Spring Security
Spring Framework - Spring SecuritySpring Framework - Spring Security
Spring Framework - Spring SecurityDzmitry Naskou
 
Spring Framework - Core
Spring Framework - CoreSpring Framework - Core
Spring Framework - CoreDzmitry Naskou
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOPDzmitry Naskou
 

Destacado (13)

Boas práticas no desenvolvimento de uma RESTful API
Boas práticas no desenvolvimento de uma RESTful APIBoas práticas no desenvolvimento de uma RESTful API
Boas práticas no desenvolvimento de uma RESTful API
 
Banco de dados no Android com Couchbase Lite
Banco de dados no Android com Couchbase LiteBanco de dados no Android com Couchbase Lite
Banco de dados no Android com Couchbase Lite
 
Design de RESTful APIs
Design de RESTful APIsDesign de RESTful APIs
Design de RESTful APIs
 
JoinCommunity 2 - Projetando um novo app usando user centered design
JoinCommunity 2 - Projetando um novo app usando user centered designJoinCommunity 2 - Projetando um novo app usando user centered design
JoinCommunity 2 - Projetando um novo app usando user centered design
 
Boas práticas no desenvolvimento de uma RESTful API
Boas práticas no desenvolvimento de uma RESTful APIBoas práticas no desenvolvimento de uma RESTful API
Boas práticas no desenvolvimento de uma RESTful API
 
Spring Framework - Validation
Spring Framework - ValidationSpring Framework - Validation
Spring Framework - Validation
 
Spring Framework - Data Access
Spring Framework - Data AccessSpring Framework - Data Access
Spring Framework - Data Access
 
Spring Framework - Expression Language
Spring Framework - Expression LanguageSpring Framework - Expression Language
Spring Framework - Expression Language
 
Spring Framework - Web Flow
Spring Framework - Web FlowSpring Framework - Web Flow
Spring Framework - Web Flow
 
Spring Framework - MVC
Spring Framework - MVCSpring Framework - MVC
Spring Framework - MVC
 
Spring Framework - Spring Security
Spring Framework - Spring SecuritySpring Framework - Spring Security
Spring Framework - Spring Security
 
Spring Framework - Core
Spring Framework - CoreSpring Framework - Core
Spring Framework - Core
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOP
 

Similar a Construção de Frameworks com Annotation e Reflection API em Java

Similar a Construção de Frameworks com Annotation e Reflection API em Java (20)

Padrões de Projeto de Software
Padrões de Projeto de SoftwarePadrões de Projeto de Software
Padrões de Projeto de Software
 
JAVA REFLETCION
JAVA REFLETCIONJAVA REFLETCION
JAVA REFLETCION
 
Padrões de design orientado a objetos
Padrões de design orientado a objetosPadrões de design orientado a objetos
Padrões de design orientado a objetos
 
Reutilização
ReutilizaçãoReutilização
Reutilização
 
Padrão De Projeto Adapter
Padrão De Projeto AdapterPadrão De Projeto Adapter
Padrão De Projeto Adapter
 
Paradigmas de Linguagens de Programação - Biblioteca de Classes e Frameworks
Paradigmas de Linguagens de Programação - Biblioteca de Classes e Frameworks Paradigmas de Linguagens de Programação - Biblioteca de Classes e Frameworks
Paradigmas de Linguagens de Programação - Biblioteca de Classes e Frameworks
 
POO2-Pre-32-PadroesProjetos_.pdf
POO2-Pre-32-PadroesProjetos_.pdfPOO2-Pre-32-PadroesProjetos_.pdf
POO2-Pre-32-PadroesProjetos_.pdf
 
Apresentação Introdução Design Patterns
Apresentação Introdução Design PatternsApresentação Introdução Design Patterns
Apresentação Introdução Design Patterns
 
pec-12-patterns-intro.ppt
pec-12-patterns-intro.pptpec-12-patterns-intro.ppt
pec-12-patterns-intro.ppt
 
Modelagem de sistemas
Modelagem de sistemasModelagem de sistemas
Modelagem de sistemas
 
Intro padroesprojetoadaptertemplateobserver
Intro padroesprojetoadaptertemplateobserverIntro padroesprojetoadaptertemplateobserver
Intro padroesprojetoadaptertemplateobserver
 
Aula1
Aula1Aula1
Aula1
 
design patterns - introdução
design patterns - introduçãodesign patterns - introdução
design patterns - introdução
 
Sld 4
Sld 4Sld 4
Sld 4
 
Mini aula-java
Mini aula-javaMini aula-java
Mini aula-java
 
DCI com PHP
DCI com PHPDCI com PHP
DCI com PHP
 
Apresentação versão 1.5
Apresentação   versão 1.5Apresentação   versão 1.5
Apresentação versão 1.5
 
Spring & Struts
Spring & StrutsSpring & Struts
Spring & Struts
 
Padrões De Projeto e Anti Patterns
Padrões De Projeto e Anti PatternsPadrões De Projeto e Anti Patterns
Padrões De Projeto e Anti Patterns
 
Interface
InterfaceInterface
Interface
 

Construção de Frameworks com Annotation e Reflection API em Java

  • 1. Frameworks com Annotations e Reflection API Fernando Camargo Desenvolvedor Java EE e Android Graduando do 4º ano de Engenharia De Computação pela UFG Estuda e programa em Java desde 2009 Em estudo para a OCJP 6
  • 4. Discussão sobre Frameworks Hora de discutir! O que significa Framework?
  • 5. Discussão sobre Frameworks ”Um framework, em desenvolvimento de software, é uma abstração que une códigos comuns entre vários projetos de software provendo uma funcionalidade genérica.”
  • 6. Exemplo Uma empresa de tecnologia, ao longo dos anos, foi desenvolvendo diversos sistemas para uso interno. Após anos, uma regra de negócio foi alterada para melhor posicionar a empresa no mercado. Essa regra era implementada em todos os sistemas internos. E agora, como alterá-la?
  • 7. Framework e biblioteca Biblioteca: Classes independentes usadas para determinadas funções (utilitários) que são chamadas pelo cliente. Framework: Interconexão de classes que trabalham em conjunto para um fim comum às várias aplicações. O cliente insere código específico que será chamado pelo código geral do Framework.
  • 8. Exemplo Depois de um projeto de 3 anos, um grupo de programadores pega um projeto parecido e com grande nível de complexidade. Vendo que poderiam reutilizar código, eles copiam e colam o que pode ser reusado nesse novo projeto. Depois de 1 ano, eles descobrem que há uma falha grave de segurança no primeiro projeto, em código comum ao 2º. Como resolver o problema dos dois? Se esse código reusável estivesse em um único lugar, seria mais fácil ou difícil?
  • 9. Framework Acima de tudo, reusável Atender as novas classes criadas, fazendo coisas específicas. Como ser reusável e ser específico ao mesmo tempo? Não possuimos nada sobre as classes que serão criadas no futuro!
  • 10. Prever o Futuro (?) Existem algumas formas de prevermos o futuro, nesse caso. Interfaces Classes abstratas Metadados
  • 11. Interfaces e Classes Abstratas Através delas, podemos prever o que poderá ser feito em tempo de compilação, mas obrigamos o cliente a assinar contratos (interfaces), implementando métodos que podem não ser de seu interesse ou tiramos sua oportunidade de usar herança, obrigando-o a fazer sua classe herdar de uma classe abstrata.
  • 12. Interfaces e Classes Abstratas Interfaces e classes abstratas podem compor um framework? Sim. Então por que não usar apenas interfaces e classes abstratas? Plug and play
  • 13. Alternativa Alternativa para deixar as classes de negócios simples e independentes: Metadados: XML e Annotations Interpretação e execução: Reflection API
  • 14. Metadados Dados que descrevem dados Mostra ao framework o que você deseja Deixa as classes limpas para implementar apenas o necessário Desvantagens: não geram erros de compilação, já que as verificações só poderão ser feitas em tempo de execução.
  • 15. Metadados (XML) Pode ser criado para configurar um framework e lhe mostrar a direção correta. Vantagem: pode ser modificado sem necessitar recompilação. Desvantagem: aplicações grandes e complexas podem gerar arquivos XML gigantes e difíceis de serem lidos.
  • 16. Metadados (Annotations) São anotações que descrevem classes, métodos, propriedades e parâmetros. São anotadas em sua própria classe, ao invés de acumuladas em um XML. Facilita a leitura e o ententimento de outros programadores Desvantagens: necessita recompilação do código, quando alterado.
  • 17. Reflection Reflection: É a habilidade de um programa observar e modificar sua própria estrutura em tempo de execução. Java provê essa habilidade através da Reflection API
  • 18. Interpretando os metadados Com Reflection, podemos interpretar os metadados que descrevem uma classe e acessar, modificar e chamar propriedades, métodos, e toda a estrutura da classe. O código interpreta os metadados e as classes descritas em tempo de execução.
  • 19. Frameworks famosos Spring (XML, Annotations e Reflection) EJB 3 (XML, Annotations e Reflection) JSF (XML, Annotations e Reflection) Hibernate (XML, Annotations e Reflections) JUnit (Classes Abstratas → Annotations)
  • 21. Introdução às Annotations Criadas na versão 1.5 do Java Têm papel de metadado Podem descrever: Classe Construtor Método Parâmetro Variável local e de instância Annotation
  • 23. @Override Informa o compilador que determinado método está sendo sobrescrito. Caso anote um método que não é herdado, ocorrerá um erro de compilação. Exemplo 1
  • 24. @SuppressWarnings Informa o compilador que determinado(s) warning(s) são de seu conhecimento e não devem ser emitidos pelo compilador. Exemplo 2
  • 25. @Deprecated Avisa aos possíveis usuários da API e o compilador que aquele método não deveria ser mais usado, pois há alternativas melhores. Exemplo 3
  • 26. As demais @Rentention, @Target, @Documented e @Inherited são meta-annotations. Usadas para descrever outras annotations e será mostrado em breve.
  • 27. Annotations criadas por Frameworks famosos @Entity: Descreve uma classe como uma unidade a ser persistida. @ManagedBean: Descreve que uma classe deve ser gerenciada pela JSF. @Named: Nomeia uma classe para ser usada em CDI. @Service: Descreve uma classe como um serviço. @Inject: Descreve que determinada instância ou parâmetro deve ser injetada.
  • 28. Criando nossas Annotations Uma Annotation é declarada da seguinte forma: public @interface Annotation{ String parametro(); }
  • 29. Classificações de Annotations Podemos separar as Annotations em várias classificações: Quanto a quantidade de parâmetros Quanto ao seu alvo Quanto a sua retenção Documentadas ou não
  • 30. Annotation de nenhum parâmetro Exemplo 4
  • 31. Annotation de único parâmetro Exemplo 5
  • 32. Annotation de múltiplos parâmetros Exemplo 6
  • 33. Tipos de Parâmetros Tipos primitivos String Class Enum Array dos tipos acima Exemplo 7
  • 34. Alvos das Annotations As annotations, quando criadas, podem definir em quais lugares podem ser aplicadas. A meta-annotation @Target indica quais elementos de código para os quais uma annotation é aplicavel. Esses alvos são: Tipo, Propriedade, Método, Parâmetro, Construtor, Variável Local e Annotation. Exemplo 8
  • 35. Retenção das Annotations As annotations também podem definer até que ponto elas devem ser consideradas. Através da meta-annotation @Retention, podemos definir que uma annotation deva ser considerada. Temos três opções: Apenas no código fonte. Durante a compilação Durante a execução (usada no Reflection) Exemplo 9
  • 36. Documentação da Annotation As annotations podem ou não aparecer no JavaDoc do projeto. Para habilitar isso, apenas anote a Annotation com: @Documented Lembre-se: Um framework não documentado é inútil!
  • 37. A meta-annotation @Inherited Indica que a annotation criada no momento será herdada em todas as subclasses. Ou seja, quando buscarmos se uma determinada classe tem essa annotation, a encontraremos caso uma superclasse a tenha. Exemplo 10
  • 38. Reflection Examinar o programa por sua estrutura e dados Tomar decisões usando os resultados do exame Mudar o comportamento, estrutura ou dados do programa baseado nas decisões O trabalho de um programador? Ou pode ser feito pelo próprio programa?
  • 39. Reflection Vamos ver agora um exemplo simples desses três passo. Exemplo 11
  • 40. Reflection - Introspection Reflection é a habilidade de um programa fazer os 3 itens ditos anteriormente. Para fazer um auto-exame, é necessário que o programa tenha uma representação de si mesmo, o que chamamos metadados. Na orientação a objetos, metadata é organizada em objetos, o que nos dá metaobjetos. A auto- examinação de um programa em tempo de execução é chamada introspection (introspecção).
  • 41. Reflection – Mudança de comportamento Existem três técnicas para fazer a mudança de comportamento em um programa: Modificação direta do metaobjeto Operações usando os metadados Intercessão (interceder em várias fases de execução do programa) Java nos traz a Reflection API várias operações usando os metadados e algumas capacidades de intercessão, mas não nos permite modificar o metaobjeto.
  • 42. Discussão Imagine a situação em que um projeto tenha várias classes de diferentes bibliotecas que compoem a interface gráfica. Algumas dessas bibliotecas não podem ser modificadas.Todas elas possuem um método setColor, que recebe um objeto do tipo Color, mas elas não implementam nenhuma interface em comum nem extendem uma superclasse.Queremos chamar esse método para qualquer desses componentes, o que faremos?
  • 43. Melhor solução para a Discussão A melhor solução para esse problema é um método que recebe um Object e faz uso de Reflection para encontrar um método setColor que receba um parâmetro Color e o chamar. Exemplo 12
  • 44. Class O objeto do tipo Class é a base da introspecção. Ele é o metaobjeto que representa determinada classe. Através dele acessamos: Campos Métodos Árvore hierárquica (superclasses e subclasses) Construtores Annotations
  • 45. Obtendo um objeto Class Temos três formas de obter o objeto Class. getClass(): Herdade de Object. Nos retorna, em tempo de execução, o objeto Class de uma determinada instância. .class: É chamado usando o nome da classe seguido por '.class'. Devemos decidir em tempo de compilação qual classe queremos. Class.forName(”className”): Retorna o objeto Class a partir do nome da classe.
  • 46. Obtendo um método Um método tem por assinatura seu nome e seus parâmetros. Podemos obtê-los da seguinte forma: getMethod: retorna um método público com dada assinatura, independente se é herdado ou declarado na classe. getDeclaredMethod: retorna um método declarado na classe, independente de sua visibilidade, a partir de sua assinatura.
  • 47. Assinatura de um método Ambos getMethod e getDeclaredMethod recebem os mesmos parâmetros: getMethod(String nomeDoMetodo, Class... parametros); Os parâmetros são um var-args de Class que representam esses parâmetros.
  • 48. Listando métodos Podemos listar todos os métodos de uma classe através dos métodos: getMethods(): retorna um array de Method de visibilidade pública, declarados ou herdados. getDeclaredMethods(): retorna um array de Method declarados na classe, independente da visibilidade.
  • 49. Discussão Vimos que passamos um var-args de Class para encontrarmos um método. Como encontrariamos um método que recebe como parâmetro uma variável primitiva, uma interface e/ou um array?
  • 50. Representando tipos através de Class Em Java, devido ao problema da discussão, todos os tipos são representados com um objeto Class. Isso inclui as Interfaces, os tipos primitivos e os arrays. Esses objetos Class não podem fazer todas as coisas que outras podem. Você não pode criar uma nova instância de um primitivo ou uma interface. Essas representações são necessária para fazer a introspecção.
  • 51. Representando tipos através de Class Após obtermos o objeto Class, podemos testar se ele representa um array, um primitivo ou uma interface através dos métodos: isArray() isPrimitive() isInterface() Veremos agora como Java representa cada um desses tipos usando objetos Class.
  • 52. Representando tipos primitivos Embora tipos primitivos não sejam objetos, Java usa objetos Class para representar todos os 8 tipos primitivos. Os primitivos são representados usando o literal 'class' após o nome do primitivo. Assim, representamos: int.class, float.class, double.class, short.class, long.class, char.class, boolean.class, byte.class Também precisamos de uma representação para void, que é representado por void.class.
  • 53. Representando interfaces Java também introduz um objeto Class para representar cada Interface declarada. Esses objetos podem ser usados para indicar parâmetros do tipo de uma interface. Obtemos o objeto Class que representa uma interface através do literal 'class'. Um exemplo seria a interface Collection, sendo representada por Collection.class.
  • 54. Representando arrays Arrays, em Java, são objetos, mas suas classes são criadas pela JVM em tempo de execução. Seus objetos Class também são obtidos através do literal 'class'. Por exemplo, um array de uma dimensão de Object é representado por Object[].class. Podemos descobrir qual o componente de um array através de getComponentType(), que retornaria um objeto Class de Object para o exemplo acima.
  • 55. Exemplo: fazendo introspecção na classe Vector Vamos fazer introspecção para pegar os seguintes métodos da classe Vector: addAll(Collection c) copyInto(Object[] anArray) get(int index) Exemplo 13
  • 56. O objeto Method Representa um método de determinada classe que tenha determinada assinatura (nome + parâmetros). Provê imformações sobre um método, como seu nome, os tipos de seus parâmetros, o tipo de seu retorno e exceções. Também dá a habilidade de invocá-lo em uma instância da classe que o declara.
  • 57. Invocação dinâmica (1) Habilita um programa a chamar um método de um objeto em tempo de execução sem especificá-lo em tempo de compilação. Object invoke(Object target, Object... parameters); Target é o objeto que terá seu método chamada. Parâmetros (var-args) são os parâmetros que o método invocado espera. O método invoke retorna um Object, o retorno do método invocado.
  • 58. Invocação dinâmica (2) O primeiro parâmetro, target, será desconsiderado em um método static, então é legal passar null. Também é legal passar null ou um nada em um método sem parâmetros. Os parâmetros são passados como Object, o que significa que são passados os Wrappers ao invés dos primitivos (Integer – int). O mesmo vale para o retorno, que retorna um Object. Um método de retorno void terá um retorno null no método invoke.
  • 59. Invocação dinâmica (3) IllegalArgumentoException será lançada quando o target não suportar o método ou quando os parâmetros estiverem incorretos. Qualquer exceção lançada dentro do método invocado lançará uma InvocationTargetException. Exemplo 14
  • 60. Discussão Temos o método getMethod para acessar métodos públicos (declarados e herdados) e temos getDeclaredMethod para acessar métodos declarados de qualquer visibilidade. Como podemos acessar um método protected de uma superclasse? Exemplo 15
  • 61. Árvore de hierarquia Podemos ter acesso à informações da árvore de hierarquia de uma classe através dos seguintes métodos: Class[] getInterfaces() Class getSuperclass() boolean isAssignableFrom(Class cls): Verificada se cls é uma subclasse. boolean isInstance(Object obj): Versão de Reflection de instanteof.
  • 62. O objeto Field Representa um campo (variável de instância) de determinada classe. É identificado pela classe o qual pertence e pelo nome. Através dele, obtemos informações sobre o tipo, o nome, os modificador e até o valor do campo de uma instância. Podemos usá-lo para pegar e modificar o valor de um campo.
  • 63. Acesso um objeto Field (1) Assim como fizemos com o objeto Method, será forma com o objeto Field. getField(String nome): retorna um campo público que tenha esse nome. getDeclaredField(String nome): retorna um campo de qualquer visibilidade declarado na classe. getFields(): retorna todos os campos públicos. getDeclaredFields():retorna todos os campos declarados.
  • 64. Acesso a um objeto Field (2) Para acessar todos os campos declarados e herdados independente de visibilidade, devemos percorrer a árvore hierarquica em busca dos campos declarados nela. Quando uma busca por um campo não o encontra, é lançada a NoSuchFieldException. Exemplo 16
  • 65. Modificadores Class, Method e Field possuem modificadores. Entre seus possíveis modificadores, podemos citar: public, private, protected, static, final, abstract, etc. Para termos acesso a esses modificadores, usamos getModifiers(), que retorna um número inteiro (vetor de bits). Para usarmos esse vetor de bits, usamos a classe Modifier para interpretá-lo. Exemplo 17
  • 66. Valor de um Field (1) Podemos acessar o valor do campo de um objeto e também modificá-lo através de Reflection. get(Object target): Retorna o valor do campo na instância target. set(Object target, Object value): Ajusta o campo, na instância target, para o novo valor 'value'. Em ambos os casos, primitivos são usados através de seus Wrappers (int – Integer)
  • 67. Valor de um Field (2) Também há um método específico para cada primitivo/wrapper. Porém, só devem ser usados caso tenha certeza do tipo do campo, ou lançaram IllegalArgumentException. getBoolean / setBoolean getInt / setInt … Exemplo 18
  • 68. Acessibilidade (1) Como visto no exemplo anterior, ao tentar acessar campos não públicos, é lançada uma IllegalAccessException. O mesmo acontece com métodos. Isso acontece porque, em tempo de execução, há uma checagem de acesso na invocação de métodos e acesso do valor de campos.
  • 69. Acessibilidade (2) Podemos contornar isso desabilitando a verificação de acessibilidade em tempo de execução. Fazemos isso usando: setAccessible(boolean param): Se true, torna o método/campo acessível via Reflection. Se false, torna inacessível. boolean isAccessible(): Verifica a situação atual do método/campo. Exemplo 19
  • 70. Desvantagens na acessibilidade Quebra o encapsulamento dos objetos. Não é uma operação ”leve”. Pode ser desabilitada em algumas JVMs. Devemos usar essa operação apenas em caso estritamente necessários. Ao contrário, devemos priorizar por chamar apenas métodos públicos e usar os getters e setters de determinado campo.
  • 71. Campo do tipo Array (1) Array é um tipo de objeto diferente que merece um tratamento especial. Para isso, o Java provê a classe Array como um facilitador nas operações com Array's em Reflection. Ele possui os seguintes métodos: getLenght(Object array): Retorna o tamanho do array. get(Object array, int i): Retorna o i-ésimo elemento do array. set(Object array, int i, Object valor): Ajusta o valor do i-ésimo elemento do array.
  • 72. Campo do tipo Array (2) newInstance(Class tipo, int length): Cria um novo array do tipo especificado com o tamanho especificado. Também temos outros métodos que devem ser consultados na API. Exemplo 20
  • 73. Reflection e Generics (1) Generics são usados em duas situações: Declarar uma classe/interface como parametrizada. Usar uma classe parametrizada. Usamos constantemente classes parametrizadas desde o Java 5. Um grande uso está nas collections, como List, Vector, Map, etc. Essa parametrização nos permite criar uma lista de String's ao invés de uma lista de Object's.
  • 74. Reflection e Generics (2) Em tempo de execução, essa parametrização é apagada da classe, já que podem haver várias instâncias com parâmetros diferentes. Mas essa informação fica disponível nos Method's, Field's, nas interfaces e superclasses parametrizadas através de Reflection. Assim como é importante saber o tipo dos componentes de um Array, também é importante saber o tipo dos objetos guardados em uma Collection nas nossas introspecções.
  • 75. Reflection e Generics (3) É importante saber que Class implementa a interface Type, pois trabalharemos com essa interface e também com ParameterizedType. Através de um Method ou um Field, teremos acesso a um ParameterizedType (que pode possuir mais de um tipo parametrizado). Através disso, acessamos a lista de Type's, que podemos dar um cast para Class e continuar nossa introspecção.
  • 76. GenericReturnType Um método pode retornar uma classe/interface parametrizada. É importante sabermos qual o tipo dessa parametrização. Usamos o método: Type getGenericReturnType() Esse método retorna um Type. Então podemos testar usando 'instanceof' se esse tipo se trata de um ParameterizedType. Caso seja, acessamos os tipos como foi descrito. Exemplo 21
  • 77. Reflection e Generics (4) É importante saber que todos os métodos ”getGeneric[...]()” retorna um Type, que pode ser um ParameterizedType. Esses métodos estão presentes em Method: getGenericReturnType(): Usado para seu retorno. getGenericParameterTypes(): Retorna um array de Type dos parâmetros. getGenericExceptionTypes(): Funciona da mesma forma para Exceptions.
  • 78. Reflection e Generics (5) Em Field: getGenericType(): Usado para verificar o tipo do campo. Em Class: getGenericInterfaces(): Retorna os tipos das interfaces implementadas pela classe. getGenericSuperclass(): Retorna o tipo da superclasse.
  • 79. Constructor (1) Uma classe possui de 1 a N construtores. É através deles que um objeto é construído. Acessando um metaobjeto Constructor, podemos construir um objeto de uma determinada classe. Podemos obter um Constructor da seguinte forma: Constructor getConstructor(Class... tiposParametros): Retorna um Constructor para os tipos de parâmetro especificados.
  • 80. Constructor (2) Constructor[] getConstructors(): Retorna todos os construtores da classe. Quando um construtor não é encontrado para determinados tipos de parâmetros, é lançada uma NoSuchMethodException, assim como acontece quando um método não é encontrado. Também acessamos os tipos de seus parâmetros através de: getParameterTypes(): Retorna as classes que representam os tipos dos parâmetros.
  • 81. Constructor (3) Possuindo uma instância do tipo Constructor, podemos criar uma nova instância da classe a qual ele pertence. Criamos uma nova instância da classe da seguinte forma: Object newInstance(Object... parametros): Cria uma nova instância da classe usando os parâmetros passados. Exemplo 22
  • 82. Constructor (4) As exceções lançadas e a acessibilidade do construtor se assemelha ao de um método. Também é válido torná-lo acessível através de setAccessible(boolean). Podemos parametrizá-lo com a classe que será construíza, caso saibamos qual é. Assim, ao invés de retornar um Object, ele retornará a classe parametrizada.
  • 83. JavaBeans e Reflection (1) JavaBeans são POJOS (Plain Old Java Objects) que serem um padrão de encapsulamento dos campos. Entre vários outras coisas especificadas, temos que os campos devem ser privados com métodos de acesso (get e set). Como vimos, devemos evitar mudar a acessibilidade dos campos com Reflection, por ser um processo pesado e romper seu encapsulamento.
  • 84. JavaBeans e Reflection (2) Padrão de métodos de acesso para campos privados: Propriedade: T xyz public T getXyz() public void setXyz(T novoValor) Propriedade: boolean xyz public boolean isXyz() public void setXyz(boolean novoValor)
  • 85. JavaBeans e Reflection (3) Devemos, sempre que possível, recorrer aos métodos de acesso para acessar campos privados. Temos duas alternativas para isso: Tratar o nome do campo para se chegar o nome correto do método de acesso. Utilizar as classes do pacote java.beans. Vamos abordar a primeira alternativa por ser mais simples. O pacote java.beans poderá ser estudado depois. Exemplo 23
  • 86. Annotations e Reflection (1) As Annotations especificadas a perdurarem até o tempo de execução poderão ser acessadas via Reflection. Assim como classes, interfaces e primitivos, as Annotations também tem uma representação através de uma Class. Uma instância com os valores definidos na anotação é representado pelo tipo Annotation. Podemos usar sua representação de Class para alcançar sua representação Annotation.
  • 87. Annotations e Reflection (2) Classes, interfaces, métodos, parâmetros, construtores e campos podem ser anotados. Dessa forma, todos possuem os métodos: Annotation getAnnotation(Class cls): Retorna uma instância do tipo da Annotation. Podemos dar um downcast para nossa annotation e usá- la para acessar os valores definidos onde foi anotada.
  • 88. Annotations e Reflection (3) Annotation[] getAnnotations(): Retorna um array com todas as annotations definidas e herdadas no elemento. Annotation[] getDeclaredAnnotations(): Retorna um array com apenas as annotations definidas no elemento. As herdadas (@Inherited) são ignoradas. Exemplo 24
  • 89. Por onde seguir Antes de apresentar o Framework final, feito com o conteúdo apresentado, segue uma lista do que falta estudar: Pacote java.beans. Proxy (interceptação de métodos) Questões de performance Classloader Geração de código
  • 90. Framework Final (1) A proposta de framework a ser implementada é a seguinte: Framework reponsável por gerenciar a sincronização de dados entre diferentes plataformas. Essa sincronização precisará de trocas de mensagens, que irão conter uma serialização dos objetos na forma de XML. As diferentes plataformas que receberem as mensagens terão um deserializador que transformará o XML de volta para um objeto.
  • 91. Framework Final (2) Usando Annotations e Reflection, nos limitaremos a implementar apenas o serializador e o deserializador de Objeto-XML. As classes dos objetos serão anotadas com algumas configurações para a serialização. Devemos criar esses Annotations e os métodos de serialização e deserialização.
  • 92. Especificando os metadados Os metadados serão compostos das seguintes annotations: @XML: Marca que uma classe pode ser serializada e deserializada em XML. Também especifica como será a serialização dos campos ou de um campo campo específico @Transient: Marca que um campo não deve ser serializado @ServerId: Marca um campo como sendo o identificador do objeto no servidor
  • 93. Eagle Sync A proposta do Framework está implementada com código fonte livre sobre licença Apache 2.0, o que dá o direito de qualquer pessoa usar o código da forma que quiser. Para ver ou contribuir com o projeto, acesse: code.google.com/p/eagle-sync/
  • 94. Referências FORMAN, I. R.; FORMAN, N. Java Reflection in Action. Manning, 2006. <http://www.developer.com/java/other/article.php/ 3556176/An-Introduction-to-Java- Annotations.htm> <http://tutorials.jenkov.com/java- reflection/index.html> <http://www.dsc.ufcg.edu.br/~jacques/cursos/ma p/html/frame/oque.htm>
  • 95. Contatos Email: fernando.camargo.ti@gmail.com Twitter: @fernandosst Facebook: www.facebook.com/fernandosst LinkedIn: br.linkedin.com/pub/fernando-camargo/ 26/21/286 Blog: fernandocamargoti.blogspot.com