A proposta hoje aqui será mostrar um exemplo básico com reflection. Quem espera encontrar algo super complexo, irá se decepcionar. Como o nome do post já diz "Primeiros passinhos - Reflection em Java" e não "Últimos passos - Domine o Reflection".
É importante ressaltar que para um entendimento pleno do post é necessário que você, caro leitor, tenha conhecimentos básicos de java e OO.
Adianto para os desesperados de plantão que é possível baixar o projeto pronto, clicando aqui.
Vamos começar então !!!
O que é reflection ? Para que serve ? Como uso ?
Todas essas perguntas serão respondidas. Reflection, em português reflexão, consiste na técnica de através de uma representação compilada de sua classe (.class), ter total acesso à ela. Quando digo total acesso, quero dizer que com o .class em mãos, é possível invocar métodos, acessar atributos e annotations, inspecionar classes e interfaces, entre outras coisas e, tudo isso em tempo de execução.
Agora você pensa: "Mas cara, ninguém usa isso !!!!"
Então eu respondo: "Você está enganado, caro leitor. Isto é usado sim e é usado por diversos frameworks. Dentre alguns, posso citar: Hibernate, Struts e Spring MVC"
Nesse momento, você abre os olhos e se pergunta: "Como ????"
Então eu, mais uma vez, respondo: "Quando você usa o Struts ou o Spring MVC e suas tags na JSP, você escreve no atributo name delas algo parecido com isso?
objeto.atributo
É, então meu amigo, não queria te enganar mas, você usa reflection sim e o pior é que você se beneficia dela. Ouso dizer que com a reflection, você atinge o backstage da classe.
Então, agora só falta responder a última pergunta: "Como uso?" Logo, vamos aos nossos exemplos.
1 - Crie a classe Pessoa
1: package br.com.pkg;
2: public class Pessoa {
3: private String codigo;
4: private String nome;
5: private String email;
6: public String empresa;
7: public String sobrenome;
8: public Integer idade;
9: public String getNome() {
10: return nome;
11: }
12: public void setNome(String nome) {
13: this.nome = nome;
14: }
15: public String getEmail() {
16: return email;
17: }
18: public void setEmail(String email) {
19: this.email = email;
20: }
21: public String getCodigo() {
22: return codigo;
23: }
24: public void setCodigo(String codigo) {
25: this.codigo = codigo;
26: }
27: public String getSobrenome() {
28: return sobrenome;
29: }
30: public void setSobrenome(String sobrenome) {
31: this.sobrenome = sobrenome;
32: }
33: public String getEmpresa() {
34: return empresa;
35: }
36: public void setEmpresa(String empresa) {
37: this.empresa = empresa;
38: }
39: public void classificar(Integer idade){
40: if(idade <= 5){
41: System.out.println("Bebê");
42: } else if(idade > 5 && idade <= 11){
43: System.out.println("Criança");
44: } else if(idade > 11 && idade <= 14){
45: System.out.println("Pré adolescente");
46: } else if(idade > 14 && idade < 18){
47: System.out.println("Adolescente");
48: } else if(idade >= 18 ){
49: System.out.println("Adulto");
50: }
51: }
52: public Integer getIdade() {
53: return idade;
54: }
55: public void setIdade(Integer idade) {
56: this.idade = idade;
57: }
58: }
2 - Crie a classe Principal
1: package br.com.pkg;
2: import java.lang.reflect.Field;
3: import java.lang.reflect.InvocationTargetException;
4: import java.lang.reflect.Method;
5: import java.util.Scanner;
6: public class Principal {
7: public static void main(String[] args) {
8: Principal principal = new Principal();
9: Class clazz = Pessoa.class;
10: principal.exibirPackage(clazz);
11: principal.exibirMetodos(clazz);
12: principal.exibirAtributos(clazz);
13: Pessoa pessoa = principal.criarPessoa(clazz);
14: principal.invocarMetodo(pessoa);
15: }
16: private void exibirMetodos(Class clazz){
17: System.out.println("==== Métodos ====");
18: Method[] methods = clazz.getMethods();
19: for(Method method : methods){
20: System.out.println("Método: " + method.getName());
21: }
22: System.out.println("\n");
23: }
24: private void exibirAtributos(Class clazz){
25: System.out.println("==== Atributos ====");
26: /*só funciona para atributos públicos*/
27: Field[] fields = clazz.getFields();
28: for(Field f : fields){
29: System.out.println("Atributo: " + f.getName() + " - Tipo: " + f.getType());
30: }
31: System.out.println("\n");
32: }
33: private void exibirPackage(Class clazz){
34: System.out.println("==== Package ====");
35: System.out.println("Package: " + clazz.getPackage().getName() + "\n\n");
36: }
37: private Pessoa criarPessoa(Class clazz){
38: System.out.println("==== Criação de objeto ====");
39: Scanner entrada = null;
40: Pessoa pessoa = new Pessoa();
41: try{
42: entrada = new Scanner(System.in);
43: Field fieldEmpresa= null;
44: Field fieldSobrenome = null;
45: Field fieldIdade = null;
46: try {
47: fieldEmpresa = clazz.getField("empresa");
48: fieldSobrenome = clazz.getField("sobrenome");
49: fieldIdade = clazz.getField("idade");
50: } catch (NoSuchFieldException e) {
51: e.printStackTrace();
52: } catch (SecurityException e) {
53: e.printStackTrace();
54: }
55: System.out.println("Digite o nome da empresa: ");
56: pessoa.setEmpresa(entrada.nextLine());
57: System.out.println("Digite o sobrenome: ");
58: pessoa.setSobrenome(entrada.nextLine());
59: System.out.println("Digite a idade: ");
60: pessoa.setIdade(Integer.valueOf(entrada.nextLine()));
61: try {
62: System.out.println("Exibição dos dados: " + fieldEmpresa.get(pessoa) + ", " + fieldSobrenome.get(pessoa) + ", " + fieldIdade.get(pessoa));
63: } catch (IllegalArgumentException e) {
64: e.printStackTrace();
65: } catch (IllegalAccessException e) {
66: e.printStackTrace();
67: }
68: } finally {
69: entrada.close();
70: }
71: return pessoa;
72: }
73: private void invocarMetodo(Pessoa pessoa){
74: System.out.println("==== Invocação de método ====");
75: try {
76: Method metodo = pessoa.getClass().getMethod("classificar", new Class[]{Integer.class});
77: System.out.println("Tipo de retorno do método: " + metodo.getReturnType());
78: System.out.println("Tipo de parâmetros: " + metodo.getParameterTypes());
79: try {
80: metodo.invoke(pessoa, pessoa.getIdade());
81: } catch (IllegalAccessException e) {
82: e.printStackTrace();
83: } catch (IllegalArgumentException e) {
84: e.printStackTrace();
85: } catch (InvocationTargetException e) {
86: e.printStackTrace();
87: }
88: } catch (NoSuchMethodException e) {
89: e.printStackTrace();
90: } catch (SecurityException e) {
91: e.printStackTrace();
92: }
93: }
94: }
IMPORTANTE
Acredito que o código está auto-explicativo mas, caso você tenha alguma dúvida, deixe-a nos comentários.
O método getMethods() e o getFields() só recuperam, respectivamente, métodos e atributos públicos. Para acesso a métodos e atributos privados, recomendo que acesse o link abaixo.
http://tutorials.jenkov.com/java-reflection/private-fields-and-methods.html
Também é importante notar que caso o método que se esteja tentando acessar é estático, é necessário passar null como primeiro argumento do método invoke. Isto acontece porque como sabemos recursos estáticos não pertencem a instância e sim a própria classe. Esta regra também é aplicada ao acesso a atributos de estáticos.
Abaixo deixo um site, o qual usei como guia para este post. Recomendo-o pois, o material escrito nele está muito bom.
http://tutorials.jenkov.com/java-reflection/index.html
Dúvidas, sugestões ou assuntos ? Deixe-os aí embaixo.
Nenhum comentário:
Postar um comentário