Reflection

Boa Noite meus caros,
Estou começando a programar em Java.
Pois bem não sei se essa é uma dúvida de iniciante… mas …
Lá vai a pergunta …
Como rodar um metodo de uma classe dinamica?
Preciso do retorno de um metodo dentro da classe dinâmica…
Consigo fazer tudo o q vi em tutoriais e tals … listar metodos … listar atributos … retorno dos tipos dos atributos … tipo do retorno dos metodos … tudo … mas não consigo obter o resultado do maldito metodo …

Estou tentando usar a API reflection …mas creio q não estou obtendo total usabiulidade dela …

Alguém pode ajudar …
Grato desde já …
Bruno

kra, tem um tutorial aki do guj que fala sobre como compilar arquivos .java em tempo de execução, carregálos e executar seus métodos. da uma olhada q vc vai encontrar o q está precisando.

Caras desculpem a ignorancia …
ainda não li o artigo q o davidbuzatto citou aí …
Mas como eu disse … sou novo em java … e pergunto a vcs se não haveria alguma outra solução ao problema q direi abaixo … sem ser o uso da API reflection …

exemplo :
Existe uma classe Pessoa.java …

public class Pessoa {
private int id_pessoa;
private String nome;

public Pessoa() {
}
  
...set .. get..

public List getDesc(){
List desc = new ArrayList();
desc.add(“NOME DA PESSOA”);
return desc;
}
}

Seria simples acessar o metodo getDesc de uma outra classe …
dessa forma ;;

  Pessoa pessoa = new Pessoa();
  
  List descricao = pessoa.getDesc();

Pois bem agora imaginem … q eu não soubesse qual classe eu usuaria …
Exemplo … no caso a classe Pessoa … viria como parametro … e teria q acessar o metodo atraves do parametro … mas como quero … fazer isso em um servlet … eu passo o parametro para ele com o nome da classe … e não a referencia da classe …
Exemplo

     String aClass = request.getParameter('CLASSE');

com isso tentava usar assim …

   class toRun = class.forName(aClass)

e aí q eu não consigo um jeito de acessar o metodo …
Será q existe um outro metódo para implementar isso ??
sem ser por meio da reflection …
ou se isso só for possivel pelo refletion … por favor me dêem uma luz …
Desde já muito grato …
Bruno

Olá Bruno, bom dia !

Estou utilizando o livro, Core Java Volume I - Fundamentos para estudar Java e me preparar para a certificação. O livro é muito bom, para se aprender Java, no meu caso estou lendo o livro e fazendo todos os exemplos e propostas do autor.
No capitulo 5 e 6 que aborda orientação a objetos, é apresentado um programa chamado ReflectionTest, esse programa deve ser digitado, e ele é muito útil para verificar como esta sendo construido cada objeto em execução, inclusive é interessante também para se realizar comparações entre classes internas e classes anonimas. Estou aprendendo muito de Java como o livro e esse programa. Segue abaixo uma adaptação desse programa para voce conseguir ver os metodos de uma classe em tempo de execução.
Estou realizando minha primeira resposta no Forum, ou seja estou estreando nesse site ! Espero que possa ter ajudado.

import java.util.;
import java.lang.reflect.
;

public class ReflectionTeste {

public static void main(String[] args) {

	String nomeDaClasse = new String("java.util.Date");
					
	try{
		
		Class classe = Class.forName(nomeDaClasse);
		Class superClasse = classe.getSuperclass();
		
		System.out.print("Class " + nomeDaClasse );
		
		System.out.println();
		imprimirMetodos( classe );
		
	}
	catch( ClassNotFoundException e ){
		e.printStackTrace();
	}
	
	System.exit(0);
}
	
public static void imprimirMetodos( Class objetoObtemInformacoes ){
	
	Method[] metodos = objetoObtemInformacoes.getDeclaredMethods();
	
	for( Method m : metodos ){
		
		Class tipoDeRetorno = m.getReturnType();
		String nome = m.getName();
		
		System.out.print("     " + Modifier.toString( m.getModifiers() ) );
		System.out.print("   " + tipoDeRetorno.getName() + "   " + nome + " ( " );
		
		Class[] tipoParametros = m.getParameterTypes();
		
		for( int j = 0; j < tipoParametros.length; j++ ){
			if( j > 0 )
				System.out.print(",   ");
			System.out.print(tipoParametros[j].getName());
		}
		
		System.out.println(" ) ;" );	
	}
}

}

atenciosamente

Domingos Bernardo

Pessoa pessoa = // objeto pessoa populado

Class klass = Class.forName( nomeDaClasse );
Method method = klass.getMethod( "getDesc" );

List list = ( List ) method.invoke( pessoa );

Só pra complementar, vai uma classe de um projeto em que participo que automatiza algumas coisinhas com reflection.

[code]package org.postgresql.projects.postgeoolap.core.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectionUtils
{
public static Object getProperty(Object object, String property)
throws NoSuchFieldException, NoSuchMethodException,
InvocationTargetException, IllegalAccessException
{
Class clazz = null;
try
{
clazz = object.getClass();

        Field field = clazz.getDeclaredField(property);
        field.setAccessible(true);
    
        return field.get(object);
    }
    catch (IllegalAccessException e)
    {
        // illegal access, try using method acessors
        String methodName = Utils.getGetMethodName(property);
        Method method = clazz.getMethod(methodName, new Class[] { });
        return method.invoke(object, new Object[] { });
    }
    
}

public static void setProperty(Object object, String property, Object value)
    throws NoSuchFieldException, IllegalAccessException 
{
    Class clazz = object.getClass();
    
    Field field = clazz.getDeclaredField(property);
    field.setAccessible(true);
    
    field.set(object, value);
}

public static Object getNestedProperty(Object object, String property)
    throws NoSuchFieldException, NoSuchMethodException, 
        InvocationTargetException, IllegalAccessException
{
    while (property.indexOf('.') != -1) 
    {
        int i = property.indexOf('.');
        String prop = property.substring(0, i); 
        property = property.substring(i + 1);
        
        object = ReflectionUtils.getProperty(object, prop);
    }
    return ReflectionUtils.getProperty(object, property);
}

public static Object invokeMethod(String methodName, Object target, Object... parameters)
{
    Class[] classes = new Class[parameters.length];
    
    for (int i = 0; i < parameters.length; i++)
        classes[i] = parameters[i].getClass();
    
    try
    {
        Method method = target.getClass().getMethod(methodName, classes);
        return method.invoke(target, parameters);
    }
    catch (Exception e)
    {
        e.printStackTrace(System.err);
        throw new IllegalArgumentException(e);
    }
}

}[/code]

Caros amigos …
Não sei se realmente não entenderam meu poroblema … ou eu não entendi a solução de vcs …
Mas de qq forma … vamos lá … vou expor o problema …mais uma vez … espero não estar enchendo vcs … =)

Bem … eu tenho uma classe Pessoa

public class Pessoa {

public Pessoa() {};

sets e gets …

public List getDesc(){
List desc = new ArrayList();

desc.add('O nome dessa classe é Pessoa ');
desc.add('Essa é uma classe criado por Bruno');
desc.add('Tem como Objetivo .... ');
desc.add('Possui alguns atributos, entre eles o Id da Pessoa e o Nome da Pessoa');

return desc;

};
}

esse metódo getDesc será comum a todos as Classes … exemplo:

public class Evento {

public Evento() {};

sets e gets …

public List getDesc(){
List desc = new ArrayList();

desc.add('O nome dessa classe é Evento ')    ;
desc.add('Essa é uma classe tem como finalidade mapear a tabela de Eventos');
desc.add('Possui alguns atributos, entre eles o Id do Evento e o Nome do Evento');
desc.add('Outro atributo de extrema importância é a data do Evento .. pois ela define ... ');

return desc;

}
}

agora com essas duas classes prontas … criamos uma pagina … JSP … q chamará um Servlet …
passando o paramêtro CLASSE … q o usuario digitará em um Input do tipo Text … A finalidade disso
é exibir aquele List …prensente no Metodo getDesc …

Quando o usuário entrasse com a Palavra(nome da classe) Pessoa … o Servlet deveria … receber esse parametro … e devolver … a descricao … do getDesc …

O nome dessa classe é Pessoa
Essa é uma classe criado por Bruno
Tem como Objetivo …
Possui alguns atributos, entre eles o Id da Pessoa e o Nome da Pessoa

Bom essa é minha dúvida … como chamar o metodo da classe … sem saber ql classe é … no exemplo acima … pode ser a classe … Pessoa ou a classe Evento … sim … pode parecer bobo isso … mas realmente seria muito útil se conseguisse fazer funcionar … se algum aí sugerir algo … agradeço … ou se alguem souber como fazer com reflection …
tb … ficaria muito agradecido …

Desde já Agradeço …
Muito grato pela atenção de vcs …
Abraços
Bruno …

Vamos lá.

[code]Class clazz = Class.forName(className);
// cria o objeto solicitado
Object object = clazz.newInstance();

// obtém e executa o método getDesc
Method method = clazz.getMethod(“getDesc”, null);
List desc = (List) method.invoke(object, null);[/code]

Através do método Class.forName você pode obter uma metaclasse a partir do nome da classe contido numa String. O método newInstance executa o construtor e retorna uma nova instância como Object (não há como saber a priori que classe será criada).

O método getMethod obtém o método desejado e Method.invoke executa este método no objeto passado como parâmetro.

Abaixo, a implementação completa:

[code]import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;

public class TesteReflection
{
public static void main(String args[])
{
String className = JOptionPane.showInputDialog(null, "Digite o nome da classe: ");
try
{
Class clazz = Class.forName(className);
// cria o objeto solicitado
Object object = clazz.newInstance();

		// obtém e executa o método getDesc
		Method method = clazz.getMethod("getDesc", null);
		List desc  = (List) method.invoke(object, null);
		for (Object o: desc)
			System.out.println(o);
	}
	catch (Exception e)
	{
		e.printStackTrace(System.err);
	}
}

}

class Pessoa {

public Pessoa() {
};

public List getDesc() {
	List desc = new ArrayList();

	desc.add("O nome dessa classe é Pessoa ");
	desc.add("Essa é uma classe criado por Bruno");
	desc.add("Tem como Objetivo .... ");
	desc
			.add("Possui alguns atributos, entre eles o Id da Pessoa e o Nome da Pessoa");

	return desc;
};

}

class Evento {

public Evento() {
};

public List getDesc() {
	List desc = new ArrayList();

	desc.add("O nome dessa classe é Evento ");
	desc.add("Essa é uma classe tem como finalidade mapear a tabela de Eventos");
	desc.add("Possui alguns atributos, entre eles o Id do Evento e o Nome do Evento");
	desc.add("Outro atributo de extrema importância é a data do Evento .. pois ela define ... ");

	return desc;
}

}[/code]

Espero ter ajudado. Vale a pena estudar metaprogramação, é útil em diversas situações. Só tome cuidado pra não viciar. :stuck_out_tongue:

Amigos … muito Obrigado … finalmente … consegui entender isso …
Valeu Rodrigo Manhães … pela grande ajuda … realmente é bem interessante … metaprogramação …rs… mas creio q só vou usar aqui …
Realmente muito bom o artigo aqui do GUJ … q ensina como criar um aplicativo para compilar código Java …
Obrigado a todos …
Abraços e até a próxima(tenho certeza q voltarei a utilizar esse forum)…

PS: A solução q usei é praticamente igual a que o Rodrigo Manhães passou no post anterior …