撰写类似
的内容时doit(43, 44, "hello");
编译器知道要调用哪个重载方法。当我想通过反思做同样的事情时,我需要找出自己,方法是
doit(Integer, double, CharSequence...);
并通过类似
的方式获取Class[] types = {Integer.class, double.class, CharSequence[].class};
declaringClass.getDeclaredMethod("doit", types);
我想知道是否已经允许我写一些东西了
Method m = getMethod(declaringClass, "doit", 43, 44, "hello");
我想知道是否有人这样做了,因为JLS在这方面有点复杂。
实际上,像Phase 1这样的完全的行为是不可能的,因为编译器只接受匹配而没有装箱和拆箱的方法。当从上面调用我假设的getMethod
时,基元和它们的包装器之间的区别已经丢失(因为通过varargs传递参数时的自动装箱)。这个问题似乎没有解决方案,所以让我们忽略它。
正如答案所示,BeanUtils.invokeMethod
接近尾声。它应该找到最佳匹配,无论它意味着什么。查看MethodUtils .getMatchingAccessibleMethod
表示
所以我正在寻找更好的东西。
答案 0 :(得分:2)
MethodHandle
是使用签名获取重载方法的新方法(java 7):
示例:
static class A {
public String get() {
return "A";
}
}
static class B extends A {
public String get() {
return "B";
}
}
public static void main(String[] args) throws Throwable {
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType mt = MethodType.methodType(String.class);
MethodHandle mh = lookup.findVirtual(A.class, "get", mt);;
System.out.println(mh.invoke(new B()));
}
输出:
B
答案 1 :(得分:1)
或者您可以使用Bean Utils from Apache Commons:
public static Method getAccessibleMethod(
Class clazz,
String methodName,
Class[] parameterTypes)
返回一个可访问的方法(也就是说,可以通过 具有给定名称和参数的反射)。如果没有这样的方法可以 发现,返回null。这只是一个方便的包装 getAccessibleMethod(方法方法)。
参数: clazz - 从此课程中获取方法 methodName - 使用此名称获取方法 parameterTypes - 使用这些参数类型
实现获取可访问的方法并在层次结构中上升,直到找到匹配为止。
为了直接按照您的要求执行调用,您可以使用同一API中的此方法:
public static Object invokeExactMethod(
Object object,
String methodName,
Object[] args,
Class[] parameterTypes)
throws
NoSuchMethodException,
IllegalAccessException,
InvocationTargetException
甚至
public static Object invokeExactMethod(
Object object,
String methodName,
Object[] args)
throws
NoSuchMethodException,
IllegalAccessException,
InvocationTargetException
首先使用getAccessibleMethod
定位方法,稍后再调用它。