10

Is this possible?

The only solutions I found usually consider a method as overriden if Class B is assignable from Class A and if Method A has the same signature as Method B. But it's not covering every cases!

For instance, I want to handle this case :

interface Foo<T> {
    void doStuff(T arg);    
}

class FooImpl implements Foo<String> {
    public void doStuff(String args) {
        //Is overriden!  
    }
}

I also want to check that Method B is actually visible to Method A (package scope etc.).

Have you ever experienced a reliable method to determine if a method is overriden?

Thank you

Simon V.
  • 1,377
  • 1
  • 14
  • 31

1 Answers1

5

There is an existing answer to determine whether a method is overriden if there is no generics involved.

Java will remove generic type entirely due to type erasure. So the bytecode would be:

class FooImpl implements Foo<java.lang.String> {
  FooImpl();
    Code:
       0: aload_0
       1: invokespecial #10                 // Method java/lang/Object."<init>":()V
       4: return

  public void doStuff(java.lang.String);
    Code:
       0: return

  public void doStuff(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #21                 // class java/lang/String
       5: invokevirtual #23                 // Method doStuff:(Ljava/lang/String;)V
       8: return
}

There is two doStuff method. It is a bridge method. It simply do type cast and invoke the void doStuff(java.lang.String), so actually void doStuff(java.lang.String) is not overriden, but void doStuff(java.lang.Object) is. When you use polymorphism like:

Foo foo = new FooImpl();
foo.doStuff("ABC")

It actually calls void doStuff(java.lang.Object). So if you use the above link to detect whether void doStuff(java.lang.Object) is overriden, it will report yes.

public static void main(java.lang.String[]);
    Code:
       0: new           #1                  // class FooImpl
       3: dup
       4: invokespecial #22                 // Method "<init>":()V
       7: astore_1
       8: aload_1
       9: ldc           #23                 // String ABC
      11: invokeinterface #25,  2           // InterfaceMethod Foo.doStuff:(Ljava/lang/Object;)V
      16: return
Community
  • 1
  • 1
StarPinkER
  • 14,081
  • 7
  • 55
  • 81
  • Very helpful, thanks for clearifying! I'm going to implement this by myself since I didn't find any libraries able to do that. If it ends up with an elegant & short solution I will post it here. – Simon V. Mar 07 '13 at 16:25
  • I just posted my solution here (written in Kotlin) : http://stackoverflow.com/questions/4821704/java-how-to-find-if-a-method-is-overridden-from-base-class – Simon V. Mar 08 '13 at 20:13