reflexão marco antonio arquiteto de software novembro/2007

24
Reflexão Marco Antonio Arquiteto de Software Novembro/2007

Upload: internet

Post on 17-Apr-2015

105 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

ReflexãoMarco AntonioArquiteto de SoftwareNovembro/2007

Page 2: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

O que é• Reflexão é geralmente utilizado por programas que

precisam modificar o comportamento de uma aplicação em tempo de execução

• É um recurso avançado e deve ser usado apenas quando o desenvolvedor tem um grande conhecimento sobre os fundamentos da linguagem

• Por outro lado, reflexão é uma técnica poderosa que faz as aplicações executar operações que seriam impossíveis de outra maneira

• Uma aplicação pode usar recursos externos, criando objetos usando apenas o nome das classes

Page 3: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

Limitações da reflexão• Reflexão é um recurso poderoso, mas não

pode ser usada de qualquer modo• Se você puder executar uma operação sem

reflexão é melhor evitá-la...

Page 4: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

Overhead• Reflexão envolve tipos que são definidos

dinamicamente, dessa forma, Java não consegue fazer todas as otimizações de um código normal

• Operações com reflexão são sempre mais lentas que as operações normais

• Essas operações devem ser evitadas em código muito executado, por questões de performance

Page 5: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

Segurança• Reflexão requer permissões especiais que

podem não estar disponíveis em ambientes seguros

Page 6: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

Exposição• Reflexão permite que você execute código

privado, o que pode resultar em comportamento não esperado

• Código com reflexão acaba com sua abstração e pode ter comportamento diferente com a atualização da plataforma

Page 7: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

Objetos dinâmicos• O ponto inicial para reflexão é

java.lang.Class• Todas as demais classes estão no pacote

java.lang.reflect

Page 8: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

ClasseReflexivapackage net.javabasico.reflexao;

public class ClasseReflexiva {

public void executaUmMetodo() {

System.out.println("Executei um método");

}

}

Page 9: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

TestaAReflexaopackage net.javabasico.testereflexao;

1. import java.lang.reflect.*;

public class TestaAReflexao { public static void main(String[] args) {2. try {3. Class clazz = Class.forName("net.javabasico.reflexao.ClasseReflexiva");4. Object objeto = clazz.newInstance();5. Method m = clazz.getMethod("executaUmMetodo");6. m.invoke(objeto);7. } catch (Exception e) {8. e.printStackTrace(); } } }

Page 10: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

Recuperando um método1. Todas as classes que você vai usar estão

nesse pacote2. Para usar reflexão é necessário o try/catch

para tratamento das exceções geradasExemplo: você pode digitar o nome do método

errado, o Eclipse não vai poder te ajudar

3. Cria um objeto do tipo Class chamado clazz (o nome poderia ser qualquer um)Vamos recuperar os métodos desse objeto através da reflexão

Page 11: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

Cont.4. Precisamos de um objeto do tipo Object

para executar (invocar) o nosso método de exemplo

5. Recupera o método baseando-se em seu nome através da reflexão

6. Executa (invoca) o método

7. Fecha o tratamento de exceção

8. Imprime os erros, caso ocorram

Page 12: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

ClasseReflexivapackage net.javabasico.reflexao;

public class ClasseReflexiva {

public String umaString = "Esse é meu valor padrão";

public void executaUmMetodo() {

System.out.println("Executei um método");

}

}

Page 13: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

TestaAReflexaopackage net.javabasico.testereflexao;

import java.lang.reflect.*;

public class TestaAReflexao { public static void main(String[] args) { try { Class clazz = Class.forName("net.javabasico.reflexao.ClasseReflexiva"); Object objeto = clazz.newInstance(); // Method m = clazz.getMethod("executaUmMetodo"); // m.invoke(objeto);1. Field atributo = clazz.getField("umaString");2. System.out.println(atributo.get(objeto)); } catch (Exception e) { e.printStackTrace(); } }}

Page 14: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

Recuperando um atributo1. Recupera o atributo pelo nome

2. Recupera e imprime o valor do atributo

Page 15: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

ClasseReflexivapackage net.javabasico.reflexao;

public class ClasseReflexiva { public String umaString = "Esse é meu valor padrão";

public void executaUmMetodo() { System.out.println("Executei um método"); } public void executaOutroMetodo(String parametro) { System.out.println("O parâmetro é: " + parametro); }}

Page 16: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

TestaAReflexaopackage net.javabasico.testereflexao;

import java.lang.reflect.*;

public class TestaAReflexao { public static void main(String[] args) { try { Class clazz = Class.forName("net.javabasico.reflexao.ClasseReflexiva"); Object objeto = clazz.newInstance();1. Method m = clazz.getMethod("executaOutroMetodo", String.class);2. m.invoke(objeto, "Marco Antonio"); } catch (Exception e) { e.printStackTrace(); } }}

Page 17: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

Método com parâmetro1. Recupera o método pelo nome, informando

qual o tipo do parâmetro. No nosso caso, o parâmetro é uma String

2. Invoca o método passando o valor. Esse valor será utilizado pelo objeto

Page 18: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

ClasseReflexivapackage net.javabasico.reflexao;

public class ClasseReflexiva { public String umaString = "Esse é meu valor padrão";

public void executaUmMetodo() { System.out.println("Executei um método"); }

public void executaOutroMetodo(String parametro) { System.out.println("O parâmetro é: " + parametro); }

public String recuperaUmValor() { return "Esse valor foi recuperado"; }}

Page 19: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

TestaAReflexaopackage net.javabasico.testereflexao;

import java.lang.reflect.*;

public class TestaAReflexao { public static void main(String[] args) { try { Class clazz = Class.forName("net.javabasico.reflexao.ClasseReflexiva"); Object objeto = clazz.newInstance();1. Method m = clazz.getMethod("recuperaUmValor");2. String s = (String) m.invoke(objeto);3. System.out.println(s); } catch (Exception e) { e.printStackTrace(); } }}

Page 20: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

Recuperando um valor1. Recupera o método pelo nome

2. Invoca o método. O sublinhado é chamado de cast, ou seja, conversão, pois o método pode retornar uma String, um Double, ou qualquer outra classe java

3. Imprime o valor de retorno do método

Page 21: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

Exercícios• Utilizando reflexão, execute todos os

métodos da classe ContaCorrente

Page 22: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

Alguns métodos utilitáriospackage net.javabasico.testereflexao;

import java.lang.reflect.*;

public class TestaAReflexao { public static void main(String[] args) { try { Class clazz = Class.forName("net.javabasico.reflexao.ClasseReflexiva");1. System.out.println(clazz.getPackage());2. for (Method m : clazz.getMethods()) {3. System.out.println(m.getName()); }4. for (Field f : clazz.getFields()) { System.out.println(f.getName()); } } catch (Exception e) { e.printStackTrace(); } }}

Page 23: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

Utilitários1. Imprime o pacote da classe

2. Estrutura conhecida como forEach (“para cada”)Exemplo: para cada método de clazz, faça algo,

no nosso caso, imprima

3. Imprime o nome de cada um dos métodos da classe

4. Imprime cada um dos atributos da classe

Page 24: Reflexão Marco Antonio Arquiteto de Software Novembro/2007

Dúvidas