超类中带有默认修饰符的Java反射访问方法

超类中带有默认修饰符的Java反射访问方法,java,reflection,Java,Reflection,是否可以通过Java反射在超类中调用no修饰符方法?是。在调用方法对象之前,可能需要对其调用setAccessible(true) Method method = getClass().getSuperclass().getDeclaredMethod("doSomething"); method.invoke(this); 如果层次结构更大,可以使用: Class current = getClass(); Method method = null; while (current != Ob

是否可以通过Java反射在超类中调用no修饰符方法?

是。在调用方法对象之前,可能需要对其调用setAccessible(true)

Method method = getClass().getSuperclass().getDeclaredMethod("doSomething");
method.invoke(this);
如果层次结构更大,可以使用:

Class current = getClass();
Method method = null;
while (current != Object.class) {
     try {
          method = current.getDeclaredMethod("doSomething");
          break;
     } catch (NoSuchMethodException ex) {
          current = current.getSuperclass();
     }
}
// only needed if the two classes are in different packages
method.setAccessible(true); 
method.invoke(this);

(以上示例适用于名为
doSomething
且没有参数的方法。如果您的方法有参数,则必须将其类型作为参数添加到
getDeclaredMethod(…)
方法)

阅读原始问题后,我意识到我假设您试图调用重写的方法。这就是我想做的,我是如何找到这条线索的。调用基类非重写方法的工作方式应与本文中的其他方法相同。但是,如果您试图调用重写的方法,我的答案如下:

我认为调用重写的方法是不可能的

最值得注意的是:

方法调用


如果基础方法是实例方法,则使用Java语言规范第二版第15.12.4.4节中记录的动态方法查找来调用它;特别是,将发生基于目标对象的运行时类型的重写

如果对子类调用getMethod和getDeclaredMethod,则两者都会失败。并且setAccessible不是必需的。从这个注释中我猜您正在尝试调用一个带有参数的方法。在查找方法时需要指定这些。请注意,指定您试图调用的方法是否已在子类中被重写是很重要的。可以通过反射调用包保护(又称默认访问)方法吗?对可以通过反射调用重写的方法吗?否,将调用重写方法。下面的答案对此问题做出了不同的假设。使用
getDeclaredMethods()
返回
Method[]
并检查是否有匹配的方法名,而不是捕获异常,这不是更好吗?后者不是很慢,因为每次都要生成堆栈跟踪吗?还是我过早地优化了?:)stacktrace是惰性生成的;如果您不请求它,则不会生成它。您可以通过在Throwable的getOurStacktrace方法中设置断点,然后抛出和异常来测试这一点。