`lookup.unreflect()`和`lookup.findVirtual()`有什么区别?

wol*_*m77 5 java reflection java-8

有两种方法我试图获得给定函数的MethodHandle.

方法1

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

方法2

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

它们之间有什么区别?

Hol*_*ger 4

显然,已经unreflect 一个解析的方法,因此\xe2\x80\x99不需要进行查找。此外,it\xe2\x80\x99s 输出取决于Method您提供的,static方法将生成调用该static方法的句柄,同时findVirtual显式请求虚拟方法调用。请记住,MyClass.class.getMethod("myMethod", String.class, Map.class)也可能会找到static接受 aString和 a 的方法Map

\n\n

此外,如果setAccessible(true)已应用于实例Method,您可能会获得一个句柄来访问其他无法访问的方法,而使用findVirtual.

\n\n

另一方面,可能会找到签名多态方法findVirtual的适当类型的调用,并且可以通过.MethodHandle.invokeMethodHandle.invokeExactjava.lang.reflect.Method

\n

  • [`MethodHandle.invokeExact`](http://docs.oracle.com/javase/8/docs/api/java/lang/invoke/MethodHandle.html#invokeExact-java.lang.Object...-) 可以是使用任意参数调用,这些参数必须与底层目标方法匹配。因此,您可以使用“lookup().findVirtual(MethodHandle.class, "invokeExact",任意类型)”反射性地执行相同的操作。相反,`MethodHandle.class .getMethod("invokeExact", …)`仅适用于`Object[].class`作为参数,调用它总是会产生`UnsupportedOperationException`。 (2认同)