我想要这样的东西
boolean match(Method method, Object... args)
如果args
匹配method
,则返回true,否则返回false。
例如
void func(int a, int b, String c) {}
如果method
代表func
,则以下调用应返回true。
match(method, 1, 2, "xxx");
以下是我目前的实施情况。
static boolean match(Method method, Object... args) {
Class[] types = method.getParameterTypes();
if (types.length != args.length)
return false;
for (int i = 0; i < args.length; i++) {
Class acceptType = types[i];
if (!acceptType.isInstance(args[i]))
return false;
}
return true;
}
上述实施存在一些问题。 它与varags参数的方法不匹配。 如果方法将float作为参数但我传递int,则它将不匹配。 还有一些其他问题,我觉得很难解决这个问题,请告诉我如何解决问题。
答案 0 :(得分:2)
您可以使用Java的 Reflection API 轻松完成此操作。它提供了分析方法签名(如参数)的方法。它甚至允许在运行时调用它们或更改代码。
请参阅以下实施:
public static boolean isApplicable(Method method, Object... args) {
Class<?>[] parameters = method.getParameterTypes();
// Length does not match
if (parameters.length != args.length) {
return false;
}
// Check classes against arguments
for (int i = 0; i < args.length; i++) {
Object argument = args[i];
Class<?> parameterType = parameters[i];
// Argument is not instance of parameter
if (!parameterType.isInstance(argument)) {
return false;
}
}
return true;
}
我们使用以下方法:
假设我们有一个类
public class Foo {
public static void bar(String text, int value) {
System.out.println(text + ", " + value);
}
}
您可以使用
之类的方法Method barMethod = Foo.class.getMethod("bar", String.class, int.class);
isApplicable(barMethod, someString, someInt); // true
isApplicable(barMethod, someString1, someString2); // false
isApplicable(barMethod, someString1, someInt, someString2); // false
有一个边缘情况会使事情变得复杂一些。即,如果基础方法使用 varargs 。然后,如果长度不匹配,则需要针对参数重复测试最后Class<?>
个参数:
public static boolean isApplicable(Method method, Object... args) {
Class<?>[] parameters = method.getParameterTypes();
// More parameters than given arguments (if varargs)
// Different length (if not varargs)
if ((method.isVarArgs() && parameter.length > args.length)
|| (!method.isVarArgs() && parameter.length != args.length)) {
return false;
}
// Check classes against arguments
for (int i = 0; i < args.length; i++) {
Object argument = args[i];
// If parameters are exhausted and method
// is using varargs, use the last parameter
Class<?> parameterType;
if (method.isVarArgs() && i > parameters.length - 1) {
parameterType = parameters[parameters.length - 1];
} else {
parameterType = parameters[i];
}
// Argument is not instance of parameter
if (!parameterType.isInstance(argument)) {
return false;
}
}
return true;
}
对于类似
的方法public static void bar(Object o, String... lines)
您的parameters
看起来像
[Class<Object>, Class<String>]
您只需将最后一个类Class<String>
重复应用于所有传入的参数。