2009-07-23 8 views
2

Angenommen, ich habe eine Schnittstelle:Widening Gleichheitsprüfung für Methodentyp

public interface FooInterface { 
     public void someMethod(); 
    } 

und ich habe eine Klasse, die diese Schnittstelle implementiert:

public class FooClass implements FooInterface { 
     public void someMethod() { 
      //do cool things 
     } 
     public void someOtherMethod() { 
      //do other cool things 
     } 
    } 

Gibt es eine einfache Möglichkeit, reflexiv zu finden, die Methode auf FooClass, die auf dem FooInterface auf die someMethod abbildet?

Ich habe etwas ähnliches wie die folgende Berechnung, aber ich war neugierig, ob jemand wusste, ein eingebautes System in Java, um diese Berechnung zu tun? Ich habe den folgenden Code ausgearbeitet, es zu tun (es Fehler sein kann, also Vorsicht):

public boolean isMethodEquality(Method meth1, Method meth2) { 

    //Check declaring classes for equality 
    boolean isAssignable; 
    isAssignable = meth1.getDeclaringClass().isAssignableFrom(
    meth2.getDeclaringClass(); 
    isAssignable |= meth2.getDeclaringClass().isAssignableFrom(
    meth1.getDeclaringClass()); 
    if (!isAssignable) { 
     return false; 
    } 
    //check the names for equality 
    if (!meth1.getName().equals(meth2.getName())) { 
    return false; 
    } 
    //check the parameters for equality 
    if (meth1.getParameterTypes().length != meth2.getParameterTypes().length) { 
    return false; 
    } 
    for (int i = 0; i < meth1.getParameterTypes().length; i++) { 
    if (!meth1.getParameterTypes()[i].equals(meth2.getParameterTypes()[i])) { 
     return false; 
    } 
    } 
    return true; 
} 

Die oben sollte die Unterschriften überprüfen. Gibt es eine andere, eingebaute Möglichkeit, dies zu tun?

Ich atmete .equals, aber das hat nicht funktioniert, was Sinn macht. Die Methoden sind verschiedene Implementierungsmuster der gleichen Methode (wobei in diesem Fall eine Deklaration ohne Definition und eine andere Definition definiert ist).

Ich weiß auch, ich könnte einfach eine vererbbare Annotation hinzufügen, aber ich würde es vorziehen, dies zu vermeiden, da dies zur Klassenexplosion führen kann.

Wie von einem der Kommentatoren erwähnt, erben Annotationen nur Klassen. Weitere Informationen finden Sie unter java docs.

Was ich wirklich suche ist ein "isAssignableFrom" für Methoden oder eine Möglichkeit, Methodensignaturen einfach zu vergleichen.

Danke.

+0

Dieser Code ist ein verstümmeltes Durcheinander ... –

+0

Bearbeitet, um den Code zu formatieren, damit es weniger verstümmelt wird :-) –

+0

Whoops - es sah nicht verstümmelt in der Vorschau aus - lass mich das tun – aperkins

Antwort

3

Die einfachste (und nein, es ist nicht gut durchzuführen, aber vermutlich etwas, das ist nicht Sie in diesem Fall interessieren würde) Weg, dies zu tun, ist concreteClass.getMethod() zu nennen:

Method interfaceMethod = ...; // method whose implementation you're looking for 
try { 
    Method implementationMethod = concreteClass.getMethod(
     interfaceMethod.getName(), interfaceMethod.getParameterTypes()); 
} catch (NoSuchMethodException E) { 
    // your class may be abstract and thus would not implement given method 
} catch (SecurityException E) { 
    // insufficient permissions 
} 
+0

Danke - das wird sehr gut funktionieren. Und für die Leistung könnten Sie den Aufruf bei Bedarf zwischenspeichern, wodurch nur einmal der Suchtreffer ausgelöst wird. Ich kann nicht glauben, dass ich das vergessen habe :) – aperkins

0

Methode implementiert gleich, so dass Sie in der Lage sein sollten, nur das zu nennen. Die Definition ist ein wenig anders als das, was Sie tun. Wenn du es speziell benötigst, um der Logik zu folgen, die du schreibst, musst du dein eigenes AFAIK rollen.

+0

Ja, der equals prüft keine Signaturen, nur dass die Methode aus derselben Klasse stammt, dieselbe Methode ist und vom selben Klassenlader geladen wurde. Ich möchte wirklich wissen, ob es sich um eine Implementierung einer anderen Methode handelt - d. H. Um eine Überschreibung. – aperkins

Verwandte Themen