Java: How to find if a method is overridden from base class?

ZZ Coder picture ZZ Coder · Jan 27, 2011 · Viewed 17.1k times · Source

How to find out if a method is overridden by child classes?

For example,

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());
}

}

Given an instance of B, how do I know if any derived classes have overridden method m() like B2?

Update: My question wasn't clear. Actually, I was trying to ask if this is possible without resorting to reflection. This check is done in a tight loop and it's used in a performance hack to save a few CPU cycles.

Answer

Jesse Barnum picture Jesse Barnum · Jan 27, 2011

I think the answers so far are assuming that you have a method and are trying to determine whether that method is overridden in a class.

However, the actual question asked was "Given an instance of B, how do I know if any derived classes have overridden method m() like B2?"

This is not possible to do using standard Java methodology, because Java does not load classes until they are referenced. For example, assume you have a URL classloader loading from a jar (or many jars) on the network. Java has no idea what classes are contained in those networked jar files, let alone whether they happen to override a particular method.

I think that I've seen utilities in Apache commons that will try to exhaustively search the hierarchy of classloaders to assemble a list of all available classes, but this sounds like a pretty bad idea to me. For one thing, it will trigger every single static initializer block for every class in the JVM.

There are some facilities like the Service Provider Interface to list class names in the jar's META-INF directory that implement a certain interface, maybe you should look at that route.