Java:如何找到一个方法是否从基类被重写?

如何确定方法是否被子类覆盖?

例如

public class Test {

static public class B {
    public String m() {return "From B";};
}

static public class B1 extends B {

}

static public class B2 extends B {
    public String m() {return "from B2";};
}

/**
 * @param args
 * @throws FileNotFoundException 
 */
public static void main(String[] args)  {

    B b1 = new B1();
    System.out.println("b1 = " + b1.m());
    B b2 = new B2();
    System.out.println("b1 = " + b2.m());
}

}

给定一个 B 的实例,我如何知道是否有任何派生类像 B2 一样重写了方法 m()?

更新:我的问题不清楚。实际上,我试图在不诉诸反思的情况下问这是否可能。此检查在紧密循环中完成,它用于性能黑客以节省几个CPU周期。


答案 1

此问题有助于演示如何获取该方法所属的类的信息:

如何快速确定方法是否在 Java 中被覆盖

class.getMethod("myMethod").getDeclaringClass();

答案 2

我认为到目前为止的答案是假设你有一个方法,并试图确定该方法是否在类中被覆盖。

然而,实际提出的问题是“给定一个B的实例,我怎么知道是否有任何派生类像B2一样重写了方法m()?

使用标准 Java 方法无法做到这一点,因为在引用类之前,Java 不会加载类。例如,假设您有一个 URL 类装入器,从网络上的一个(或多个 jar)加载。Java不知道这些联网的jar文件中包含哪些类,更不用说它们是否碰巧覆盖了特定的方法。

我认为我已经在Apache共享资源中看到过实用程序,它们将尝试详尽地搜索类加载器的层次结构以组装所有可用类的列表,但这对我来说听起来是一个非常糟糕的主意。首先,它将触发 JVM 中每个类的每个静态初始值设定项块。

有一些工具,如服务提供者接口,可以在jar的META-INF目录中列出实现某个接口的类名,也许你应该看看这个路由。


推荐