Trabalhando com Métodos usando a Classe Method em Java
A classe Method, do pacote java.lang.reflect, representa um método de uma classe ou interface.
Ela fornece meios para inspecionar as definições dos métodos e chamá-los dinamicamente.
Principais métodos:
String getName(): retorna o nome do método.Class[] getExceptionTypes(): retorna, como um array de objetosClass, os tipos de exceções que o método pode lançar.int getModifiers(): retorna um valor inteiro cujos bits indicam os modificadores aplicados.int getParameterCount(): retorna a quantidade de parâmetros do método.Class[] getParameterTypes(): retorna um array de objetosClassque representa os tipos dos parâmetros.Class getReturnType(): retorna o tipo de retorno do método.Object invoke(Object obj, Object... args): chama o método representado, no objeto especificado, com os argumentos informados.
Obtendo Métodos
A classe Class oferece métodos para acessar os métodos de uma classe:
Method[] getMethods(): retorna um array com todos os métodos públicos da classe, incluindo os herdados de superclasses.Method[] getDeclaredMethods(): retorna um array com todos os métodos definidos na classe, independentemente do modificador de acesso.Method getMethod(String name, Class... parameterTypes): retorna um método público com o nome e a lista de tipos de parâmetros especificados; a busca também inclui métodos herdados. Se não existir, lançaNoSuchMethodException.Method getDeclaredMethod(String name, Class... parameterTypes): retorna um método definido na própria classe, independentemente do modificador de acesso. Se não existir, lançaNoSuchMethodException.
Exemplo: Obtendo Todos os Métodos
import java.lang.reflect.*;
public class Program {
public static void main(String[] args) {
Class<?> cl = Operation.class;
Method[] methods = cl.getDeclaredMethods();
for (Method m : methods) {
System.out.println(m);
}
}
}
class Operation {
static int sum(int val1, int val2) {
return val1 + val2;
}
static double sum(double val1, double val2) {
return val1 + val2;
}
static int subtract(int val1, int val2) {
return val1 - val2;
}
}Saída:
static int Operation.sum(int,int) static double Operation.sum(double,double) static int Operation.subtract(int,int)
Inspecionando um Método
O exemplo abaixo mostra como obter informações detalhadas sobre o método sum que recebe dois parâmetros int:
import java.lang.reflect.*;
public class Program {
public static void main(String[] args) {
Class<?> cl = Operation.class;
try {
// Obtém o método sum com dois parâmetros int
Method m = cl.getDeclaredMethod("sum", int.class, int.class);
String methodName = m.getName();
String modifiers = Modifier.toString(m.getModifiers());
int paramsCount = m.getParameterCount();
Class<?> retType = m.getReturnType();
Class<?>[] paramTypes = m.getParameterTypes();
System.out.print(modifiers + " " + retType.getName() + " " + methodName + "(");
for (int j = 0; j < paramsCount; j++) {
if (j > 0) System.out.print(", ");
System.out.print(paramTypes[j].getName());
}
System.out.println(");");
} catch (Exception ex) {
System.out.println(ex);
}
}
}
class Operation {
static int sum(int val1, int val2) {
return val1 + val2;
}
static double sum(double val1, double val2) {
return val1 + val2;
}
static int subtract(int val1, int val2) {
return val1 - val2;
}
}Saída:
static int sum(int, int);
Chamando Métodos com invoke
O método invoke(Object obj, Object... args) chama dinamicamente o método representado.
O primeiro parâmetro obj indica o objeto no qual o método será chamado. Para métodos estáticos, esse parâmetro é ignorado e pode ser null.
O segundo parâmetro args é um array com os argumentos a serem passados para o método.
O valor de retorno de invoke é o resultado do método chamado.
Chamando um Método Estático
import java.lang.reflect.*;
public class Program {
public static void main(String[] args) {
Class<?> cl = Operation.class;
try {
Method m = cl.getDeclaredMethod("sum", int.class, int.class);
int val1 = 23;
int val2 = 4;
int result = (int) m.invoke(null, val1, val2);
System.out.printf("sum(%d, %d) = %d%n", val1, val2, result);
} catch (Exception ex) {
System.out.println(ex);
}
}
}
class Operation {
static int sum(int val1, int val2) {
return val1 + val2;
}
static int subtract(int val1, int val2) {
return val1 - val2;
}
}Saída:
sum(23, 4) = 27
Chamando um Método de Instância
import java.lang.reflect.*;
public class Program {
public static void main(String[] args) {
Person tom = new Person("Tom");
Class<?> cl = tom.getClass();
try {
Method m = cl.getDeclaredMethod("setName", String.class);
String name = "Programício";
m.invoke(tom, name);
tom.print(); // Person Programício
} catch (Exception ex) {
System.out.println(ex);
}
}
}
class Person {
private String name;
void setName(String name) { this.name = name; }
Person(String name) { this.name = name; }
void print() {
System.out.println("Person " + name);
}
}Saída:
Person Programício
Acessando Métodos Privados
Por padrão, não é possível acessar métodos privados por reflexão.
Para habilitar o acesso, o método precisa ser tornado acessível com setAccessible(true).
import java.lang.reflect.*;
public class Program {
public static void main(String[] args) {
Person tom = new Person("Tom");
Class<?> cl = tom.getClass();
try {
Method m = cl.getDeclaredMethod("setName", String.class);
m.setAccessible(true); // habilita o acesso
String name = "Programício";
m.invoke(tom, name);
tom.print(); // Person Programício
} catch (Exception ex) {
System.out.println(ex);
}
}
}
class Person {
private String name;
private void setName(String name) { this.name = name; }
Person(String name) { this.name = name; }
void print() {
System.out.println("Person " + name);
}
}Saída:
Person Programício
Resumo
- A classe
Methodfornece acesso às informações e à execução de métodos de uma classe. - Os métodos
getMethods()egetDeclaredMethods()listam os métodos públicos ou todos os métodos definidos. - Os métodos
getMethod()egetDeclaredMethod()recuperam métodos específicos conforme nome e parâmetros. - Métodos como
getName(),getReturnType(),getParameterTypes()egetModifiers()permitem inspecionar as características de um método. - O método
invoke()chama métodos estáticos ou de instância dinamicamente. - Métodos privados podem ser acessados após habilitar o acesso com
setAccessible(true).