Upload
internet
View
110
Download
1
Embed Size (px)
Citation preview
Metaprogramação – API Reflection da linguagem Java
Paulo Eduardo Papotti
Prof. Dr. Antonio Francisco do Prado
Metraprogramação
“Metaprogramação é a programação de programas que escrevem ou manipulam outros programas (ou a si próprios) assim como seus dados.”
Vantagens→ Maior produtividade
→ Menos código
Desvatagens→ Maior cuidado na hora de programar
→ Nem todas as linguagens oferecem esse recurso
Metaclasse
“Em orientação a objetos, uma metaclasse é uma classe cujas instâncias também são classes e não objetos no sentido tradicional. Assim como classes definem o comportamento de certos objetos, metaclasses definem o comportamento de certas classes e suas instâncias.”
Em Java:Class classe = Aluno.class;
Fatorial em tempo de compilação
#include <iostream>using namespace std;
template <int N> // Esta é a definição do templatestruct Fatorial { static const int valor = N * Fatorial<N - 1>::valor;};
template <> // Esta é a definição do caso basestruct Fatorial<0> { static const int valor = 1;};
int main (int argc, char *argv[]) { cout << Fatorial<5>::valor << endl; cout << Fatorial<2>::valor << endl; return 0;}
Java Reflection API
Java manipulando Java
Uma das capacidades incomuns do Java é que um programa pode analisar a si próprio.
É possível descobrir: A classe de um objeto Modificadores de acesso, superclasse, campos, construtores e
métodos. Se a classe implementa uma interface.
É possível fazer: Criar instancia da classe Obter e modificar a variaveis de instância. Invocar um método de uma classe.
Para que serve Reflection?
Em programas comuns não é necessário usar Reflection.
Usa-se Reflection se o seu programa necessita processar o próprio programa ou outros programas.
Exemplos típicos:» Um navegador de classes» Um depurador» Um construtor de GUI» Uma IDE, tal como Netbeans ou Eclipse
A classe Class Para obter informações sobre uma classe, é
necessário seu objeto Class.» Se você tem um objeto obj, você pode obter seu
objeto classe através:Class c = obj.getClass();
» Você pode obter a classe da superclasse de uma Class c através:Class sup = c.getSuperclass();
» Se você souber o nome da classe em tempo de compilação, você pode obter seu objeto classe através:Class c = Aluno.class;
» Se você souber o nome da classe em tempo de execução em uma String str, o objeto classe pode ser obtido através:Class c = class.forName(str);
Obetndo o nome da classe
Se você tem uma classe de objeto c, pode-se obter o nome da classe com o comando c.getName()
getName retorna o nome completo da classe (incluindo pacotes), Class c = Button.class; String s = c.getName(); System.out.println(s);irá exibir: java.awt.Button
A classe Class e seus métodos estão em java.lang, que é um pacote de classes que sempre é importado para qualquer programa Java.
Obtendo os modificadores de um objeto Class
Os modificadores (public, final, abstract etc.) de um objeto Class podem ser acessados através do método getModifiers().
Um modifier é na verdade um int mas a classe Modifier possui métodos para definir qual é o tipo do modificador. Por exemplo:
if (Modifier.isPublic(m)) System.out.println("public");
Obtendo os modificadores de um objeto Class
Modifier contém esses métodos (entre outros):
» public static boolean isAbstract(int)» public static boolean isFinal(int)» public static boolean isInterface(int)» public static boolean isPrivate(int)» public static boolean isProtected(int)» public static boolean isPublic(int)» public static String toString(int)
Obtendo interfaces
Para saber quais interfaces um objeto Class implementa basta chamar o método getInterfaces(), que retorna um array de objetos Class.
Ex:
static void printInterfaceNames(Object o) {Class c = o.getClass();Class[] allInterfaces = c.getInterfaces();for (Class inf: allInterfaces) {
System.out.println(inf.getName());}
}
Examinando classes e interfaces
A classe Class representa tanto classes quanto interfaces
Para determinar se um objeto c do tipo Class é uma interface, use-sa c.isInterface()
Métodos úteis de um objeto Class são:» getModifiers()» getFields()» getConstructors()» getMethods()» isArray()
Obtendo Fields public Field[] getFields() throws SecurityException
» Retorna um array de Field (somente atributos públicos incluindo atributos herdados).
» O tamanho do array pode ser zero» Não existe uma ordem definida para retornar os
atributos, mas, em geral, eles vem na ordem que foram declarados
» pulic Field getField(String name) throws NoSuchFieldException, SecurityException
» Retorna o objeto Field de um determinado atributo (apenas público)
» Para acessar atributos privados também, usa-se o método public Field[] getDeclaredFields() e pulic Field getDeclaredField(String name)
Usando Fields Se f é um objeto Field então
» f.getName() retorna o nome simples do atributo
» f.getType() retorna o tipo (Class) do atributo
» f.getModifiers() retorna os Modifiers do atributo
» f.toString() retorna uma String contendo modificadores de acesso, o tipo, e o nome completo do atributo
» Example: public java.lang.String Person.name
Usando Fields
Os atributos de um objeto obj podem ser acessador através:
» boolean f.getBoolean(obj), int f.getInt(obj), double f.getDouble(obj), etc., retornam o valor do atributo desde que seja do tipo correto (tipos primitivos)
» Object f.get(obj) retorna o atributo (objetos)» void f.set(obj, value), void f.setBoolean(obj,
bool), void f.setInt(obj, i), void f.getDouble(obj, d), etc. seta o valor do atributo;
Obtendo Construtores de uma classe
Se c é um objeto Class, então c.getConstructors() : Constructor[] retorna um
array de todos os construtores públicos de uma da classe c.
c.getConstructor( Class … paramTypes ) retorna um construtor que possua os mesmos parâmetros dados por paramTypes.
Ex: String.class.getConstructors().length> 15; // A classe String possui 15 construtores
públicos String.class.getConstrucor( char[].class, int.class,
int.class).toString()> String(char[], int,int).
Construtores Se c é um objeto Constructor, então
» c.getName() retorna o nome do construtor em uma String (é o mesmo nome da classe)
» c.getDeclaringClass() retorna a Class no qual o construtor foi declarado
» c.getModifiers() retorna os Modifier do construtor
» c.getParameterTypes() retorna um array de objetos Class na ordem que foram declarados
» c.newInstance(Object… initargs) cria e retorna um nova instância da classe c
Exemplo
Constructor c = String.class.getConstrucor( char[].class, int.class, int.class).toString()
String(char[], int,int).
String s = c.newInstance( new char[] {‘a’,’b’,’c’,’d’ }, 1,
2 );
s = “bc”;
A classe Method
public Method[] getMethods() throws SecurityException
Retorna um array de objetos Method (apenas métodos públicos de uma classe ou interface, incluindo métodos herdados)
Não há ordem específicas que os métodos são retornados
public Method getMethod(String name, Class… parameterTypes)throws NoSuchMethodException, SecurityException
Methods getDeclaringClass() → Retorna o objeto Class representando a classe ou
interface que declarou o método
getName() → Retorna o nome do método em uma String
getModifiers() → Retorna os modificadores do método em formato
int.
getParameterTypes() → Retorna um array de objetos Class que
representam os tipos dos parâmetros do método em questão.
Methods
getReturnType() → Retorna o objeto Class que representa o tipo de
retorno do método
toString() → Retorna uma String que descreve o método
public Object invoke(Object obj, Object… args)→ Invoca o método, de um determinado objeto com
parâmetros especificados.
Examplos de invoke()
“abcdefg”.length()>> 7 Method lengthMethod =
String.class.getMethod(“length”) ; lengthMethod.invoke(“abcdefg”)>> 7 “abcdefg”.substring(2, 5)>> cde Method substringMethod =
String.class.getMethod ( “substring”, int.class, Integer.TYPE ) ;
substringEMthod.invoke( “abcdefg”, 2, new Integer(5) )
> > cde
Obtendo membros não públicos de uma classe
Todos as chamadas getXXX() métodos da classe Class mencionados retorna apenas membros public da classe alvo.
Para obter também membros privados, protegidos, estático existem chamadas do tipo getDeclaredXXX()
getDeclaredConstructors(), getDeclaredConstrucor(Class…)
getDeclaredFields(), getDeclaredField(String) getDeclaredmethods(), getDeclaredMethod(String, Class…)
Mais informações
Documentaçãohttp://download.oracle.com/javase/7/docs/technotes/guides/lang/index.html
Exemplos de códigoshttp://java.sun.com/developer/codesamples/refl.html