Are you working with Java Reflection? Having trouble invoking your methods through reflection? Wish there was a simple way to call an arbitrary method on an object?
|
Swans Reflecting Elephants (1937) - Dali |
/*
* Copyright © 2013 - Elliott Frisch
*
* THIS SOFTWARE IS PROVIDED UNDER THE CREATIVE COMMONS
* LICENSE 3.0 "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR
* A PARTICULAR PURPOSE.
*
* To use this software you must agree to the complete
* license terms available at:
* http://creativecommons.org/licenses/by/3.0/us/deed.en_US
*
* It is the intent of the author(s) that you may use or
* modify this software for any purpose (including your own
* commercial gain) provided that this notice remains in its
* entirety.
*
* Created by Elliott Frisch - www.frischcode.com
*/
package com.frischcode.util;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.math.BigDecimal;
/**
* <b>Rationale:</b> Provide a mechanism to generically call
* a method.
*
* @author Elliott Frisch
*/
public class MethodUtil {
/**
* Returns the size (or length) of an array.
*
* @param obj
* The Array to find the size of .
* @return The length of the array (if object is an
* array), or 0.
*/
private static int safeSize(Object obj) {
if (obj != null) {
return Array.getLength(obj);
}
return 0;
}
/**
* If it exists, invoke methodName on receiver - passing
* parameters (if they exist) as arguments. If
* receiver.methodName(parameters) returns, return the
* returned value.
*
* @param receiver
* The receiver to invoke.
* @param methodName
* The name of the method to call.
* @param parameters
* The arguments to pass to the method.
* @return The value returned from invoking methodName on
* receiver.
* @throws Exception
* Any Exception thrown by invoking the method
* with the passed parameters.
*/
public static Object callMethod(Object receiver,
String methodName, Object... parameters)
throws Exception {
if (receiver == null || methodName == null) {
return null;
}
methodName = methodName.trim();
if (methodName.length() == 0) {
return null;
}
Class<?> cls = receiver.getClass();
Method toInvoke = null;
outer: for (Method method : cls.getMethods()) {
if (!methodName.equals(method.getName())) {
continue;
}
Class<?>[] mTypes = method.getParameterTypes();
if (parameters == null && mTypes == null) {
toInvoke = method;
break;
} else if (safeSize(mTypes) == 0
|| safeSize(parameters) == 0) {
continue;
} else if (safeSize(mTypes) != safeSize(parameters)) {
continue;
}
for (int i = 0; i < mTypes.length; ++i) {
if (!mTypes[i].isAssignableFrom(parameters[i]
.getClass())) {
continue outer;
}
}
toInvoke = method;
break;
}
if (toInvoke != null) {
try {
return toInvoke.invoke(receiver, parameters);
} catch (Exception t) {
throw t;
}
}
return null;
}
/**
* A small sample program. Prints 100. Prints 200.
*
* @param args
*/
public static void main(String[] args) {
try {
BigDecimal a = new BigDecimal("99");
a = (BigDecimal) callMethod(a, "add",
new BigDecimal("1"));
System.out.println(a);
System.out.println(callMethod(a, "multiply",
new BigDecimal("2")));
System.out.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}
No comments :
Post a Comment