【问题标题】:Java reflection accessing method with default modifier in the super class超类中带有默认修饰符的Java反射访问方法
【发布时间】:2010-01-20 09:56:09
【问题描述】:

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

【问题讨论】:

  • 请注意,指定您尝试调用的方法是否已在子类中被覆盖,这一点很重要。您可以通过反射调用受包保护(也称为默认访问)的方法吗?是的。您可以通过反射调用重写的方法吗?不,将调用覆盖方法。下面的答案对这个问题做出了不同的假设。

标签: java reflection


【解决方案1】:
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(...)方法)

【讨论】:

  • 使用getDeclaredMethods() 返回Method[] 并检查我们是否有匹配的方法名称而不是捕获异常不是更好吗?后者不是很慢,因为每次都必须生成堆栈跟踪吗?还是我过早优化? :)
  • Stacktraces 是懒惰生成的;如果您不请求它,则不会生成它。您可以通过在 Throwable 的 getOurStacktrace 方法中设置断点然后抛出异常来测试。
【解决方案2】:

在阅读了原始问题之后——我意识到我假设您正在尝试调用一个被覆盖的方法。这就是我想要做的以及我是如何找到这个线程的。调用基类非覆盖方法应该像这里其他人所描述的那样工作。但是,如果您尝试调用被覆盖的方法,我的回答如下:

我不认为调用被覆盖的方法是可能的,每

http://blogs.oracle.com/sundararajan/entry/calling_overriden_superclass_method_on

最值得注意的是:

方法调用

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

【讨论】:

    【解决方案3】:

    是的。在调用 Method 对象之前,您可能需要调用它的 setAccessible(true)。

    【讨论】:

    • 如果在子类上调用 getMethod 和 getDeclaredMethod 都会失败。并且不需要 setAccessible。
    • 从该评论中我猜您正在尝试使用参数调用方法。您需要在查找方法时指定这些。
    猜你喜欢
    • 1970-01-01
    • 2011-04-13
    • 1970-01-01
    • 2016-06-15
    • 2015-10-14
    • 2017-02-19
    • 2011-04-10
    • 2012-11-12
    • 2013-04-16
    相关资源
    最近更新 更多