2013-03-07 10 views
10

Ist das möglich?Ermitteln, ob eine Methode eine andere mit Reflektion überschreibt?

Die einzigen Lösungen, die ich in der Regel gefunden betrachten ein Verfahren, wie außer Kraft gesetzt, wenn Class B von Class A zuweisbare ist und wenn Method A hat die gleiche Signatur wie Method B. Aber es deckt nicht alle Fälle ab!

Zum Beispiel möchte ich diesen Fall behandeln:

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

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

Ich mag auch prüfen, ob Method B tatsächlich sichtbar ist Method A (Paketbereich etc.).

Haben Sie schon einmal eine zuverlässige Methode kennengelernt, um festzustellen, ob eine Methode überschrieben wurde?

Danke

+1

Nicht zu vergessen die optionale Anmerkung "@ Overridable". –

Antwort

3

Es ein existing answer ist, um zu bestimmen, ob eine Methode überschriebene ist, wenn es keine Generika beteiligt.

Java entfernt generischen Typ vollständig aufgrund type erasure. Der Bytecode wäre also:

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 
} 

Es gibt zwei doStuff-Methode. Es ist ein bridge method. Es gibt einfach cast ein und ruft void doStuff (java.lang.String) auf, so dass void doStuff (java.lang.String) nicht überschrieben wird, aber void doStuff (java.lang.Object) ist. Wenn Sie Polymorphismus wie verwenden:

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

Es tatsächlich ruft Leere doStuff (java.lang.Object). Wenn Sie also den obigen Link verwenden, um zu ermitteln, ob void doStuff (java.lang.Object) überschrieben wurde, wird yes gemeldet.

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 
+0

Die Antwort wurde aktualisiert. @ user1642427 – StarPinkER

+0

Sehr hilfreich, danke für die Klärung! Ich werde das selbst implementieren, da ich keine Bibliotheken gefunden habe, die das können. Wenn es mit einer eleganten und kurzen Lösung endet, werde ich es hier veröffentlichen. –

+0

Ich habe gerade meine Lösung hier (geschrieben in Kotlin) geschrieben: http://StackOverflow.com/Questions/4821704/java-how-to-find-if-a-method-is-overridden-from-base-class –

Verwandte Themen