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

问题描述 投票:-2回答:2

我想使用反射测试私有方法。在这种情况下,来自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. 它看起来非常基本和直观,为什么会发生这种情况?
java reflection junit
2个回答
1
投票

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


0
投票

你遇到的问题是在线

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

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

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

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

method.setAccessible(true);
method.invoke(food);
© www.soinside.com 2019 - 2024. All rights reserved.