为什么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
}
我的问题是:
- 我应该在第二个参数中添加什么才能使其正常工作?更改
getDeclaredMethod("isEdible", Boolean.class)
仍然会抛出相同的异常。 - 它看起来非常基本和直观,为什么会发生这种情况?
答案
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?的主要内容,如果未能解决你的问题,请参考以下文章
java反射 - getXXX 与 getDeclaredXXX
java的反射机制之getDeclaredMethods和getMethods的区别