簡単な解決策がありますが、その単純さにはパフォーマンスが犠牲になります。
代わりにこのモンスターを使用しています。
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()
。それらの一部またはすべてが null になることもあります。次に、非プリミティブ パラメータ フィールドのマットとして扱われます。
これでも完全ではありません。ポリモーフィックに適したメソッドがいくつかあるが、どれも完全に一致しない場合、返されるメソッドは任意に選択され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();
}
さらにブーストするには、ある種のキャッシュを検討してください。