Java reflection utility to get method with compatible parameters
May 26, 2011 21:16:22 Last update: June 02, 2011 14:39:57
Given a class
it is OK to call method
However, if you find method by parameter types with Java reflection, the types must match exactly, i.e.,
This is a utility to find methods with compatible parameter types:
Example usage:
A:
class A { public int doWork(String s, int i, boolean b) { System.out.printf("Doing work: string(%s), int(%s), boolean(%s)\n", s, i, b); return 1; } }
it is OK to call method
doWork with both primitive types and the corresponding wrapping object types:
new A().doWork("Hello", 1, false); new A().doWork("Hello", new Integer(2), Boolean.TRUE);
However, if you find method by parameter types with Java reflection, the types must match exactly, i.e.,
Class<?> c = Class.forName("A"); // This call finds the doWork method Method m1 = c.getMethod( "doWork", Class.forName("java.lang.String"), int.class, boolean.class ); // This call throws exception Method m2 = c.getMethod( "doWork", Class.forName("java.lang.String"), Class.forName("java.lang.Integer"), Class.forName("java.lang.Boolean") );
This is a utility to find methods with compatible parameter types:
import java.lang.reflect.*; import java.util.*; public class ReflectionUtil { private static Map<Class,Class> primitiveMap = new HashMap<Class,Class>(); static { primitiveMap.put(boolean.class, Boolean.class); primitiveMap.put(byte.class, Byte.class); primitiveMap.put(char.class, Character.class); primitiveMap.put(short.class, Short.class); primitiveMap.put(int.class, Integer.class); primitiveMap.put(long.class, Long.class); primitiveMap.put(float.class, Float.class); primitiveMap.put(double.class, Double.class); } public static Method getCompatibleMethod(Class c, String methodName, Class... paramTypes) { Method[] methods = c.getMethods(); for (int i = 0; i < methods.length; i++) { Method m = methods[i]; if (!m.getName().equals(methodName)) { continue; } Class<?>[] actualTypes = m.getParameterTypes(); if (actualTypes.length != paramTypes.length) { continue; } boolean found = true; for (int j = 0; j < actualTypes.length; j++) { if (!actualTypes[j].isAssignableFrom(paramTypes[j])) { if (actualTypes[j].isPrimitive()) { found = primitiveMap.get(actualTypes[j]).equals(paramTypes[j]); } else if (paramTypes[j].isPrimitive()) { found = primitiveMap.get(paramTypes[j]).equals(actualTypes[j]); } } if (!found) { break; } } if (found) { return m; } } return null; } }
Example usage:
Method m = ReflectionUtil.getCompatibleMethod(c, "doWork", Class.forName("java.lang.String"), Class.forName("java.lang.Integer"), Class.forName("java.lang.Boolean") ); m.invoke(c.newInstance(), "String", new Integer(1), new Boolean(false));