为什么getDeclaredMethod与Class作为第二个参数抛出NoSuchMethodException?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么getDeclaredMethod与Class作为第二个参数抛出NoSuchMethodException?相关的知识,希望对你有一定的参考价值。

我想使用反射测试私有方法。在这种情况下,来自isEdible类的Food方法。

public class Food {

  private Boolean isEdible() {
    return true;
  }
}

当我在没有指定Food类的情况下使用getDeclaredMethod时,它运行成功。

@Test
  public void foodTestOne() throws Exception {
    Food food = new Food();
    Method method = food.getClass().getDeclaredMethod("isEdible");
    method.setAccessible(true);
    boolean isEdible = (boolean) method.invoke(food);
    assertTrue(isEdible);
  }

但是当我在第二个参数上添加Food Class时,我得到了NoSuchMethodException

@Test
  public void foodTestTwo() throws Exception {
    Food food = new Food();
    Method method = food.getClass().getDeclaredMethod("isEdible", Food.class);
    // execution stop here
  }

我的问题是:

  1. 我应该在第二个参数中添加什么才能使其正常工作?更改getDeclaredMethod("isEdible", Boolean.class)仍然会抛出相同的异常。
  2. 它看起来非常基本和直观,为什么会发生这种情况?
答案

getDeclaredMethod需要匹配方法所期望的参数类型。当一个方法不带参数(例如isEdible())时,你可以传递null(或一个空的Class[]),例如

public class Food {

    private Boolean isEdible() {
        return true;
    }

    public static void main(String[] args) {
        Food food = new Food();
        try {
            Class<?>[] methodArgumentTypes = null; // {};
            Object[] methodArguments = null; // new Object[0];
            Method method = food.getClass().getDeclaredMethod("isEdible", 
                    methodArgumentTypes);
            System.out.println(method.invoke(food, methodArguments));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

实际上会调用isEdible()并输出true

另一答案

你遇到的问题是在线

Method method = food.getClass().getDeclaredMethod("isEdible", Food.class);

您指定Food作为方法的参数;它不是。相反,你应该有

Method method = food.getClass().getDeclaredMethod("isEdible");

isEdible()被声明为私有,因此即使使用getDeclaredMethod,您也无法在当前上下文中访问它。要允许访问,可以在调用方法之前将其设置为可访问。

method.setAccessible(true);
method.invoke(food);

以上是关于为什么getDeclaredMethod与Class作为第二个参数抛出NoSuchMethodException?的主要内容,如果未能解决你的问题,请参考以下文章

面试记录

getDeclaredMethod 抛出异常

java反射 - getXXX 与 getDeclaredXXX

java的反射机制之getDeclaredMethods和getMethods的区别

JavaSE8基础 Class getDeclaredMethods 获取类的所有方法(不包括父类的)

JAVA 反射之Method