2015-04-09 2 views
5

Es gibt 2 Möglichkeiten, das MethodHandle für eine bestimmte Funktion zu erhalten.Was ist der Unterschied zwischen `lookup.unreflect()` und `lookup.findVirtual()`?

Methode 1

Method m = MyClass.class.getMethod("myMethod", String.class, Map.class); 
MethodHandle mh = MethodHandles.lookup().unreflect(m); 

Methode 2

MethodType type = MethodType.methodType(void.class, String.class, Map.class); 
MethodHandle mh = MethodHandles.lookup().findVirtual(MyClass.class, "myMethod", type); 

Was ist der Unterschied zwischen den beiden von ihnen?

Antwort

3

Offensichtlich hat unreflect eine aufgelöste Methode bereits, daher muss nicht eine Suche durchgeführt werden. Außerdem hängt seine Ausgabe von der von Ihnen angegebenen Method-Methode ab. Eine static-Methode liefert einen Handle, der die static-Methode aufruft, während findVirtual explizit eine virtuelle Methodenaufruf anfordern. Beachten Sie, dass MyClass.class.getMethod("myMethod", String.class, Map.class) auch eine static Methode finden kann, die eine String und eine Map akzeptiert.

Wenn ferner setAccessible(true) hat auf die Method Instanz angelegt wurde, können Sie einen Griff bekommen eine sonst unzugängliche Methode Zugriff auf der Verwendung von findVirtual nicht möglich ist.

Auf der anderen Seite, findVirtual Anrufungen der Signatur polymorphen Methoden finden können über java.lang.reflect.Method zugegriffen MethodHandle.invoke und MethodHandle.invokeExact die nicht werden in geeigneter Weise eingegeben.

+0

konnte den letzten Punkt nicht verstehen. – wolfram77

+2

['MethodHandle.invokeExact'] (http://docs.oracle.com/javase/8/docs/api/java/lang/invoke/MethodHandle.html#invokeExact-java.lang.Object...-) kann mit beliebigen Argumenten aufgerufen werden, die mit der zugrunde liegenden Zielmethode übereinstimmen müssen. Sie können also 'lookup(). FindVirtual (MethodHandle.class," invokeExact ", arbitraryType) verwenden, um das gleiche zu tun. Im Gegensatz dazu funktioniert 'MethodHandle.class .getMethod (" invokeExact ", ...)' nur mit 'Object []. Class' als Argument, und das Aufrufen desselben erzeugt immer eine' UnsupportedOperationException'. – Holger

+0

ging über meinen Kopf @Holger (ich bin neu in der Reflexion). Aber, danke für die Antwort. 'unreflect' scheint eine gute Wahl zu sein, da ich auch mit statischen Methoden arbeiten möchte. (Warum würden Sie 'findVirtual' auf' MethodHandle' selbst verwenden?) – wolfram77

Verwandte Themen