I have prepared a functional example of how the method with varied arguments should be called.
The main idea is you should pass an array of parameters to the invoke, only that the arguments of variable size must be another array that will be the last element of the main array.
Consider the comments in the code that explain step-by-step what it does:
class Exemplo {
private static Object invokeMethodPrivateClassBase(
Class<?> clazz,
Object instance,
String nameMethod,
List<Class<?>> paramsTypeClazz,
Object... args) {
try {
//localiza o método
Method method = clazz.getDeclaredMethod(
nameMethod,
paramsTypeClazz.toArray(new Class[paramsTypeClazz.size()]));
//torna-o acessível mesmo sendo private
method.setAccessible(true);
//verifica se tem argumentos variados
if (method.isVarArgs()) {
//cria um array de parâmetros que deve ter a exata quantidade de parâmetros declarados,
//isto é, sem considerar os argumentos variantes
Object[] parameters = new Object[paramsTypeClazz.size()];
//copia os parâmetros fixos para o novo array, desconsiderando apenas o último que é variante
System.arraycopy(args, 0, parameters, 0, paramsTypeClazz.size() - 1);
//calcula quantos argumentos variantes foram passados
int varArgsSize = args.length - paramsTypeClazz.size() + 1;
//cria um array com o tipo dos parâmetros variantes
Object varArgsParameter = Array.newInstance(
paramsTypeClazz.get(paramsTypeClazz.size() - 1).getComponentType(),
varArgsSize);
//copia todos os demais argumentos para o array de argumentos variantes
System.arraycopy(args, paramsTypeClazz.size() - 1, varArgsParameter, 0, varArgsSize);
//coloca o array de argumentos variantes como último parâmetro para o método a ser chamado
//isso porque o "..." equivale a um array
parameters[paramsTypeClazz.size() - 1] = varArgsParameter;
//chama o método
return method.invoke(instance, parameters);
} else {
return method.invoke(instance, args);
}
} catch (Throwable e) {
//apenas para teste
System.out.println(e.getMessage());
}
return "Y";
}
/**
* Método de exemplo a ser chamado via reflexão
*/
public String meuMetodo(String label, Integer... valores) {
Integer soma = 0;
for (Integer v : valores) soma += v;
return label + ": " + soma;
}
public static void main (String[] args) throws java.lang.Exception {
//modo normal
System.out.println(new Exemplo().meuMetodo("S1", 3, 4, 1));
//prepara lista de tipos dos argumentos
List<Class<?>> paramsTypeClazz = new ArrayList<Class<?>>();
paramsTypeClazz.add(String.class);
paramsTypeClazz.add(Integer[].class);
//modo reflexivo
System.out.println(Exemplo.invokeMethodPrivateClassBase(
Exemplo.class,
new Exemplo(),
"meuMetodo",
paramsTypeClazz,
"S1", 3, 4, 1));
}
}
Converting to
arraydoes not work? Using thetoArray?– Wakim
@Wakim, yes, I had just seen this here, and see that
T..., is nothing more thanT[], then I’ll just take mineList<T> listand give alist.toArray()As you said, thanks. If you can/want to elaborate a good answer for future research, I’ll analyze it later. (There are times when simple things seem complicated, hehe).– Fernando Leal