sexta-feira, 29 de julho de 2011

Java - método chamarMetodo() - método utilitário para chamar um método qualquer dinamicamente em Java via Reflection


Java - método chamarMetodo() - método utilitário para chamar um método qualquer dinamicamente em Java via Reflection

Oi pessoal,

Hoje vou mostrar um método utilitário para chamar um método qualquer dinamicamente em Java via Reflection:

/**
* Chama um método dinamicamente (via Reflection).
*
* @param classeExecutora - A Classe onde está o método a ser chamado.
* @param objetoExecutor - Uma instância da classeExecutora que irá executar o método. Se o
* método a ser chamado for um método static, neste parâmetro deve vir null.
* @param nomeMetodo - O nome do método a ser chamado.
* @param arrayClassesParametros - Um array com as Classes dos parâmetros do método a ser
* chamado.
* @param arrayObjetosParametros - Um array com as instâncias (os valores) dos parâmetros do
* método a ser chamado.
* @return Object - o retorno do método desejado (se o mesmo tiver algum retorno, senão
* retorna null)
*/
@SuppressWarnings("unchecked")
public static Object chamarMetodo(Class classeExecutora, Object objetoExecutor,
String nomeMetodo, Class[] arrayClassesParametros, Object[] arrayObjetosParametros) {
if (nomeMetodo == null || "".equals(nomeMetodo.trim())) {
throw new RuntimeException(
"chamarMetodo() - O nome do método que deveria ser chamado está vazio.");
}
if (arrayClassesParametros == null) {
// se o araryClassesParametros estah null, cria um array vazio
arrayClassesParametros = new Class[] {};
}
if (arrayObjetosParametros == null) {
// se o arrayObjetosParametros estah null, cria um array vazio
arrayObjetosParametros = new Object[] {};
}
Object retorno = null;

// vai chamar o método desejado
Method metodo;
try {
metodo = classeExecutora.getMethod(nomeMetodo, arrayClassesParametros);
} catch (NullPointerException e) {
throw new RuntimeException(
"chamarMetodo() - A classeExecutora (a classe que deveria chamar " +
"o método desejado) está nula. Error: " + e);
} catch (NoSuchMethodException e) {
throw new RuntimeException("chamarMetodo() - O método chamado (" +
classeExecutora.getName() + "." + nomeMetodo + "()" +
") não foi encontrado. Error: " + e);
}

try {
retorno = metodo.invoke(objetoExecutor, arrayObjetosParametros);
} catch (InvocationTargetException e) {
throw new RuntimeException(
"chamarMetodo() - Erro desconhecido ao chamar o método \"" +
nomeMetodo + "\" com os parâmetros \"" + arrayObjetosParametros +
"\".\n\nExceção gerada: " + e + " ##### Target do Erro: " +
e.getTargetException());

} catch (IllegalAccessException e) {
throw new RuntimeException(
"chamarMetodo() - Erro desconhecido ao chamar o método \"" +
nomeMetodo + "\" com os parâmetros \"" + arrayObjetosParametros +
"\".\n\nExceção gerada: " + e);
}
return retorno;
}

Com este método, fica muito mais fácil chamar um método qualquer via Reflection. Veja como funciona com os exemplos abaixo:

1 - Digamos que eu tenho uma classe MeuTeste com o seguinte método:

public Map testando(String nome, TesteVO testeVO);

Para chamar o método, fazemos o seguinte:

MeuTeste meuTeste = new MeuTeste();
TesteVO testeVO = new TesteVO();

Map mapaRetorno = (Map)chamarMetodo(MeuTeste.class, meuTeste, "testando", new Class[] { String.class, TesteVO.class }, new Object[] { "Rodison", testeVO });

Dessa forma, o método será chamado via Reflection.

Chamar um método desta forma permite muitas possibilidades, principalmente se você está fazendo métodos utilitários que poderão ser reutilizados em N projetos para automatizar trechos de código.

Vamos para o segundo exemplo.

2 - Vamos chamar a mesma função mas sem parâmetros:

public Map testando2();

Para chamar o método, fazemos o seguinte:

MeuTeste meuTeste = new MeuTeste();

Map mapaRetorno = (Map)chamarMetodo(MeuTeste.class, meuTeste, "testando2", null, null);

3 - Chamando um método void:

public void testando3();

Para chamar o método, fazemos o seguinte:

MeuTeste meuTeste = new MeuTeste();

chamarMetodo(MeuTeste.class, meuTeste, "testando3", null, null);

4 - Chamando um método estático:

public static RetornoVO testandoEstatico(String texto);

Para chamar o método, fazemos o seguinte:

RetornoVO retornoVO = (RetornoVO)chamarMetodo(MeuTeste.class, null, "testandoEstatico", new Class[] {String.class}, new Object[] {"texto qualquer"});

Para chamar um método estático repare que o segundo argumento do chamarMetodo deve ser null (pois um método estácio é chamado diretamente sem precisar a classe do método).

Bem, é isso. Mais uma funçãozinha pra facilitar a vida da gente :)

flw,

Rodison

Nenhum comentário: