I need to call a private method via reflection. In advance I don't kow if that private method is part of the specified class or a super class. My first approach was the following:
Object classToTest = ....;
ArrayList<Method> methods = new ArrayList<Method>();
Class<?> classIndex = classToTest.getClass();
//iterate over (super) classes to collect all methods
do{
methods.addAll(Arrays.asList(classIndex.getDeclaredMethods()));
classIndex = classIndex.getSuperclass();
}
while(classIndex.getClass()!=null);
for(Method method : methods){
//match the right method
}
//call it
method.setAccessible(true);
method.invoke(classToTest,parameterValues);
Problem with that approach: Getting the right method out of the list is not trivial as the sourcecode for .getDeclaredMethod(...) shows. Unfortunatly many private internal methods are used...
The 2nd approach was to use the getDeclaredMethod() which does the matching for me:
Method method=null;
Class<?> classIndex = classToTest.getClass();
//iterate over (super) classes since private method may be inherited
do{
//exception catching as part of the normal code is ugly
try{
method = classIndex.getDeclaredMethod(nameOfMethod, parameterTypes);
//method found thus exit
break;
}
catch(NoSuchMethodException nsme){
//method not found thus check super class
classIndex = classIndex.getSuperclass();
}
}
while(classIndex!=null);
if(method==null) throw new NoSuchMethodException( classToTest.getClass().getName() + "." + nameOfMethod + Arrays.toString(parameterValues));
//no method matching necessary
method.setAccessible(true);
method.invoke(classToTest,parameterValues);
Disadvantage of that approach: the exception catching as part of the code flow is ugly - however I currently don't see an alternative without reimplementing the matching code of Class.java.
So does anyone see an alternative approach to get the right private method?
Aucun commentaire:
Enregistrer un commentaire