Java: resolução do método de tempo de execução
Estou trabalhando em alguma invocação dinâmica de código por meio de um intérprete e estou entrando nas áreas difíceis e feias da resolução de métodos, conforme discutido emJLS seção 15.12.
A maneira "fácil" de escolher um método é quando você conhece os tipos exatos de todos os argumentos; nesse momento, você pode usarClass.getDeclaredMethod(String name, Class[] parameterTypes)
. Talvez você precise verificar a acessibilidade do método e as superclasses / superinterfaces da classe.
Mas isso não cobre nenhum dos seguintes casos, por isso é meio inútil:
primitivas de boxe / unboxing subtipos varargsm argumento nulo (que pode ser de qualquer tipo, a menos que o intérprete saiba de outra forma; no momento da compilação, qualquer ambiguidade seria eliminada lançando nulo a uma classe / interfaconversão de tipo @primitive (não faz parte do Java, mas é permitida no contexto de linguagens - por exemplo, Rhino Javascript, onde todos os números são de ponto flutuante, portanto o código Java pode levar umint
mas o chamador passa um número que é umint
oudouble
)(veja abaixo um exemplo rápido dos três primeiros)
Então agora eu tenho que escrever minha própria biblioteca de resolução de métodos ...
Existe alguma biblioteca de estrutura conhecida para ajudar niss
package com.example.test.reflect;
import java.lang.reflect.Method;
public class MethodResolutionTest {
public void compute(int i) { /* implementation... */ }
public void compute(Long l) { /* implementation... */ }
public void compute(Object obj) { /* implementation... */ }
public void compute(String... strings) { /* implementation... */ }
public static void main(String[] args) {
Class<?> cl = MethodResolutionTest.class;
/* these succeed */
findAndPrintMethod(cl, "compute", int.class);
findAndPrintMethod(cl, "compute", Long.class);
findAndPrintMethod(cl, "compute", Object.class);
findAndPrintMethod(cl, "compute", String[].class);
/* these fail */
findAndPrintMethod(cl, "compute", Integer.class);
findAndPrintMethod(cl, "compute", long.class);
findAndPrintMethod(cl, "compute", MethodResolutionTest.class);
findAndPrintMethod(cl, "compute", String.class, String.class);
}
private static void findAndPrintMethod(Class<?> objectClass,
String methodName, Class<?>... parameterTypes)
{
try {
Method method = findMethod(objectClass, methodName,
parameterTypes);
System.out.println(method.toString());
}
catch (SecurityException e) {
e.printStackTrace();
}
catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
private static Method findMethod(Class<?> objectClass,
String methodName, Class<?>[] parameterTypes)
throws SecurityException, NoSuchMethodException
{
return objectClass.getDeclaredMethod(methodName, parameterTypes);
}
}