如何在Java中找到重载方法?

maa*_*nus 16 java reflection overloading

写点的时候

doit(43, 44, "hello");
Run Code Online (Sandbox Code Playgroud)

编译器知道要调用哪个重载方法.当我想通过反思做同样的事情时,我需要找出自己,方法是

doit(Integer, double, CharSequence...);
Run Code Online (Sandbox Code Playgroud)

并通过类似的东西获得它

Class[] types = {Integer.class, double.class, CharSequence[].class};
declaringClass.getDeclaredMethod("doit", types);
Run Code Online (Sandbox Code Playgroud)

我想知道是否已经允许我写一些东西了

Method m = getMethod(declaringClass, "doit", 43, 44, "hello");
Run Code Online (Sandbox Code Playgroud)

我想知道是否有人这样做了,因为JLS在这方面有点复杂.


实际上,行为与编译器完全相同是不可能的,因为在第1阶段,编译器只接受匹配而没有装箱和拆箱的方法.当getMethod从上面调用我的假设时,原语和它们的包装器之间的区别已经丢失(因为通过varargs传递参数时的自动装箱).这个问题似乎没有解决方案,所以让我们忽略它.

如答案所示,BeanUtils.invokeMethod接近.它应该找到最佳匹配,无论它意味着什么.查看MethodUtils.getMatchingAccessibleMethod显示了这一点

  • 它对varargs一无所知
  • 这是非确定性的

所以我正在寻找更好的东西.

Fra*_*eth 1

或者,您可以使用Apache Commons 中的 Bean Utils

public static Method getAccessibleMethod(
        Class clazz,
        String methodName,
        Class[] parameterTypes)
Run Code Online (Sandbox Code Playgroud)

根据文件

返回具有给定名称和参数的可访问方法(即可以通过反射调用的方法)。如果找不到这样的方法,则返回 null。这只是 getAccessibleMethod(Method method) 的一个方便的包装。

参数: clazz - 从此类获取方法 methodName - 获取具有此名称的方法 parameterTypes - 具有这些参数类型

该实现获取可访问的方法并在层次结构中向上移动,直到找到与之匹配的方法。

直接调用

为了按照您的要求直接执行调用,您可以从同一 API 使用此方法:

public static Object invokeExactMethod(
        Object object,
        String methodName,
        Object[] args,
        Class[] parameterTypes)
        throws
        NoSuchMethodException,
        IllegalAccessException,
        InvocationTargetException
Run Code Online (Sandbox Code Playgroud)

甚至

public static Object invokeExactMethod(
        Object object,
        String methodName,
        Object[] args)
        throws
        NoSuchMethodException,
        IllegalAccessException,
        InvocationTargetException
Run Code Online (Sandbox Code Playgroud)

首先使用找到该方法getAccessibleMethod,然后调用它。