Tuesday, November 15, 2011

Invoking Method via Reflection

These are snippets from an old object I use from time to time, the "InstanceType" is a generic type of the enclosing class, you may replace it with Object or '?' respectively


First of all we need to get the method instance:


/**
* Searches for the method with the specified parameters in the supplied class object.

* @param _class The class which contains the method with the specified parameters.
* @param methodName The method name to search for.
* @param parameterTypes The method parameters types.
* @return The method instance of the supplied class.
* @throws MethodNotFoundException if a method with the supplied specifications was not found.
*/
private Method findAMethod(Class<InstanceType> _class, String methodName, Class<?>... parameterTypes)
throws MethodNotFoundException {
Method[] methods = _class.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
if (!methods[i].getName().equals(methodName))
continue;
if (compareMethodParametersTypes(parameterTypes, methods[i].getParameterTypes()))
return methods[i];
}
throw new MethodNotFoundException("There was no match for method: \n  " + methodName + "("
+ ReflectiveTools.parseParametersType(parameterTypes) + "); \n  In the specified class object: " + _class.getName());
}

Next we need to invoke the method, with its parameters, which may be called synchronously,or asynchronously:

public final Object invokeMethod(InstanceType instance, Object... parameters)
throws MethodInvocationException {
try {
checkParameters(parameters);
return method.invoke(instance, parameters);
} catch (IllegalArgumentException e) {
throw new MethodInvocationException(method, instance, parameters, e);
} catch (IllegalAccessException e) {
throw new MethodInvocationException(method, instance, parameters, e);
} catch (InvocationTargetException e) {
throw new MethodInvocationException(method, instance, parameters, e);
} catch (WrongParameterType e) {
throw new MethodInvocationException(method, instance, parameters, e);
}
}
public final <ReturnType> void invokeMethodAsynch(final InstanceType instance, final MethodInvocationCompleted<ReturnType> notifyer, final Object... parameters) {
Runnable methodInvocationRun = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
try {
Object returnValue = invokeMethod(instance, parameters);
if (notifyer != null)
notifyer.methodInvocationCompleted((ReturnType) returnValue);
} catch (MethodInvocationException e) {
if (notifyer != null)
notifyer.handleException(e);
}
}
};
Thread t = new Thread(methodInvocationRun, "Invocation of method: " + ReflectiveTools.getMethodAsString(method));
t.start();
}

The Notifier interface should be implemented when called asynchronously:

public interface MethodInvocationCompleted<ReturnType> {
void handleException(MethodInvocationException e);
void methodInvocationCompleted(ReturnType returnValue);
}

Have Fun.

No comments:

Post a Comment