有一个简单的解决方案,但这种简单是以性能为代价的。
我正在使用这个怪物:
public static Method findMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) throws NoSuchMethodException {
// First try the trivial approach. This works usually, but not always.
try {
return clazz.getMethod(methodName, parameterTypes);
} catch (NoSuchMethodException ex) {
}
// Then loop through all available methods, checking them one by one.
for (Method method : clazz.getMethods()) {
String name = method.getName();
if (!methodName.equals(name)) { // The method must have right name.
continue;
}
Class<?>[] acceptedParameterTypes = method.getParameterTypes();
if (acceptedParameterTypes.length != parameterTypes.length) { // Must have right number of parameters.
continue;
}
boolean match = true;
for (int i = 0; i < acceptedParameterTypes.length; i++) { // All parameters must be right type.
if (null != parameterTypes[i] && !acceptedParameterTypes[i].isAssignableFrom(parameterTypes[i])) {
match = false;
break;
}
if (null == parameterTypes[i] && acceptedParameterTypes[i].isPrimitive()) { // Accept null except for primitive fields.
match = false;
break;
}
}
if (match) {
return method;
}
}
// None of our trials was successful!
throw new NoSuchMethodException();
}
parameterTypes
是你从你的value.getClass()
. 它们中的一些或全部也可以为空。然后它们被视为任何非原始参数字段的匹配。
即使这样也不是完美的:如果有几个方法在多态上是合适的,但没有一个完全匹配,那么返回的方法是任意选择的(clazz.getMethods()
返回数组中的第一个匹配项)。此行为不同于 Java 语言行为,其中始终使用“最接近的匹配”。
如果按名称获取方法就足够了(即,如果名称匹配,您假设参数是合适的),那么您可以更简单(并且更快)进行管理:
public static Method findMethod(Class<?> clazz, String methodName) {
for (Method method : clazz.getMethods()) {
if (method.getName().equals(methodName)) {
return method;
}
}
throw new NoSuchMethodException();
}
为了进一步提高它,考虑某种缓存。