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
array
does 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> list
and 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