Wie bekomme ich die MethodInfo einer Java 8 Methodenreferenz?
Bitte haben Sie einen Blick auf den folgenden code:
Method methodInfo = MyClass.class.getMethod("myMethod");
Dies funktioniert, aber den Namen der Methode als Zeichenfolge übergeben wird, so wird diese kompilieren auch wenn myMethod nicht vorhanden.
Auf der anderen Seite, Java 8 stellt eine Methode Funktion Verweis. Es wird überprüft, zum Zeitpunkt der Kompilierung. Es ist möglich, verwenden Sie diese Funktion, um die Methode get info?
printMethodName(MyClass::myMethod);
Vollständigen Beispiel:
@FunctionalInterface
private interface Action {
void invoke();
}
private static class MyClass {
public static void myMethod() {
}
}
private static void printMethodName(Action action) {
}
public static void main(String[] args) throws NoSuchMethodException {
//This works, but method name is passed as a string, so this will compile
//even if myMethod does not exist
Method methodInfo = MyClass.class.getMethod("myMethod");
//Here we pass reference to a method. It is somehow possible to
//obtain java.lang.reflect.Method for myMethod inside printMethodName?
printMethodName(MyClass::myMethod);
}
In anderen Worten, ich würde gerne ein code-was ist das äquivalent zu der folgenden C# - code:
private static class InnerClass
{
public static void MyMethod()
{
Console.WriteLine("Hello");
}
}
static void PrintMethodName(Action action)
{
//Can I get java.lang.reflect.Method in the same way?
MethodInfo methodInfo = action.GetMethodInfo();
}
static void Main()
{
PrintMethodName(InnerClass.MyMethod);
}
InformationsquelleAutor der Frage Rafal | 2013-11-07
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nein, es gibt keine zuverlässige, unterstützte Weg, dies zu tun. Weisen Sie eine Methode Referenz auf eine Instanz einer funktionalen Schnittstelle, aber diese Instanz ist, gekocht von
LambdaMetaFactory
und es gibt keine Möglichkeit zu bohren, um zu finden, die Methode, die Sie ursprünglich gebunden.Lambdas und Methode Referenzen in Java funktionieren ganz anders als Delegaten in C#. Für einige interessante Hintergrundinformationen Lesen
invokedynamic
.Anderen Antworten und Kommentare hier zeigen, dass es derzeit möglich, zum abrufen der gebundenen Methode mit etwas zusätzliche Arbeit, aber stellen Sie sicher, Sie verstehen die Vorbehalte.
InformationsquelleAutor der Antwort Mike Strobel
Sieht aus wie es möglich sein könnte, nachdem alle, durch die Verwendung eines proxy aufzeichnen, welche Methode aufgerufen wird.
https://stackoverflow.com/a/22745127/3478229
InformationsquelleAutor der Antwort ddan
Obwohl ich noch nicht selber ausprobiert, ich denke, die Antwort ist "Nein", da eine Methode Referenz ist semantisch das gleiche wie ein lambda.
InformationsquelleAutor der Antwort Matt Ball
In meinem Fall war ich auf der Suche nach einem Weg, um loszuwerden, diese in unit-tests:
Wie Sie sehen können jemand testen der Methode
getAPoint
und prüft, ob die Koordinaten sind wie erwartet, aber in der Beschreibung der einzelnen geltend machen, die kopiert wurde und nicht in sync mit dem, was geprüft wird. Besser wäre zu schreiben, dies nur einmal.Aus den Ideen von @ddan baute ich eine proxy-Lösung mit Mockito:
Nein, ich kann einfach verwenden
sowie die Beschreibung der Geltendmachung ist garantiert synchron mit dem code.
Nachteil:
Aber es zeigt einen Weg, wie es getan werden könnte.
InformationsquelleAutor der Antwort yankee
Wenn du die Schnittstelle
Action
erweiternSerializable
dann diese Antwort aus einer anderen Frage scheint eine Lösung zu bieten (zumindest bei einigen Compilern und Laufzeitumgebungen).InformationsquelleAutor der Antwort user102008
Verlag haben wir die kleine Bibliothek de.cronn:Reflexion-utildie verwendet werden können, um zu erfassen eine Methode Namen.
Beispiel:
Umsetzung details: Ein Proxy-Unterklasse
MyClass
erstellt mit ByteBuddy und ein Aufruf der Methode erfasst wird, ruft dessen Namen.ClassUtils
speichert die Informationen, so dass wir nicht brauchen, um erstellen Sie einen neuen proxy auf jede Anrufung.Bitte beachten Sie, dass dieser Ansatz funktioniert nicht mit statische Methoden.
InformationsquelleAutor der Antwort Benedikt Waldvogel
Versuchen, diese
InformationsquelleAutor der Antwort Asghar Nemati
Kann es nicht sein, einen zuverlässigen Weg, aber unter gewissen Umständen:
MyClass
ist nicht endgültig, und verfügt über eine Behindertengerechte Konstruktor (Beschränkung der cglib)myMethod
ist nicht überladen, und nicht statischDen können Sie versuchen, mithilfe von cglib zum erstellen einer proxy
MyClass
dann mit einemMethodInterceptor
zu berichten, dieMethod
während die Methode Referenz aufgerufen wird, wird in einem folgenden Versuch laufen.Beispiel-code:
Sehen Sie die folgende Ausgabe:
Während:
Im obigen code
MethodRefWith1Arg
ist nur ein syntax-Zucker für, einen Verweis auf eine nicht statische Methode mit einem Argumente. Sie können beliebig viele zu erstellenMethodRefWithXArgs
für die Referenzierung von Ihren anderen Methoden.InformationsquelleAutor der Antwort vivimice
So Spiele ich mit diesem code
Ausgabe dieses Codes ist:
Und als ich merke index der referenzierten Methode ist immer 30.
Der endgültige code sieht wie
Seien Sie vorsichtig mit diesem code in der Produktion!
InformationsquelleAutor der Antwort Dmitriy V.
Können Sie "meine Bibliothek"
Reflektieren, Ohne String
InformationsquelleAutor der Antwort Dean Xu