Java反射getDeclaredMethod抛出NoSuchMethodException异常

时间:2019-08-27 09:57:37

标签: java reflection

我有一个要在类getListSonarMetricsFromRegistry中声明的私有方法SonarRestApiServiceImpl,该方法要用Java反射调用,但出现异常:

  

java.lang.NoSuchMethodException:com.cma.kpibatch.rest.impl.SonarRestApiServiceImpl.getListSonarMetricsFromRegistry(java.util.HashMap)       
在java.lang.Class.getDeclaredMethod(Class.java:2130)       
在com.test.service.rest.SonarRestApiServiceImplTest.testGetListSonarMetricsFromRegistry(SonarRestApiServiceImplTest.java:81)


我尝试使用Java反射,如下所示:

    @Test
    public void initTest() throws NoSuchMethodException, SecurityException, IllegalAccessException,
            IllegalArgumentException, InvocationTargetException {
        Map<Long, KpiMetric> tmp = new HashMap<>();
        Method method = sonarRestApi.getClass().getDeclaredMethod("getListSonarMetricsFromRegistry", tmp.getClass());
        method.setAccessible(true);
        List<String> list = (List<String>) method.invoke(sonarRestApi, registry.getKpiMetricMap());
    }

这是getListSonarMetricsFromRegistry方法声明:

//This method works correctly, it returns a List of String without error
private List<String> getListSonarMetricsFromRegistry(Map<Long, KpiMetric> map) {
    return //something
}

当我查看异常时,跟踪将使用正确的包,正确的名称,正确的方法名称和正确的参数打印我的Class:

  

com.test.rest.impl.SonarRestApiServiceImpl.getListSonarMetricsFromRegistry(java.util.HashMap)   但是它说这种方法不存在,这很奇怪。

Stackoverflow提供的类似问题确实有帮助,但我仍然有相同的异常。

1 个答案:

答案 0 :(得分:1)

我认为您的问题是,您给一个HashMap类实例作为getDeclaredMethod的参数,而该方法实际上接受了Map类实例。请记住,所有通用参数都是在编译时删除的,因此在运行时进行反射时,Map<Whatever,WhateverElse>会变成Map。因此,尝试:

 Method method = sonarRestApi.getClass().getDeclaredMethod("getListSonarMetricsFromRegistry", Map.class);

在相关说明中,基于反射调用私有API进行测试可能不是使测试长期保持可维护性的好方法。我不确定为什么需要这样做,但是如果可以的话,请尝试找到一种适用于公共API的方法。