33

随着 Java 7 的发布MethodHandle,它允许用户调用一个方法,就像使用它的底层字节码一样。特别是,MethodHandles.Lookup该类提供工厂方法来创建方法句柄以访问类成员:

Lookup 对象上的工厂方法对应于方法、构造函数和字段的所有主要用例。工厂方法创建的每个方法句柄都是特定字节码行为的功能等价物。

从功能上讲,这或多或少等同于使用反射来访问这些相同的类成员,但方法句柄比反射更快

那么,是否有任何理由仍然使用反射功能,例如Field#get(..)/Method.invoke(..)或者这些方法是否随着引入更快的方法句柄而有效过时?

请注意,虽然方法句柄是在 Java 7 中引入的,但我的问题主要与 Java 8 相关,在 Java 8 中,它们被优化以达到与直接字段/方法调用大致相等的性能,超过了反射的能力。

4

2 回答 2

40

反射和方法句柄服务于不同的目的,并且存在于不同的抽象级别。您应该使用适合您正在解决的问题的那个。

反射是一种通用的自省机制,它包含了方法句柄机制所缺乏的许多特性,例如枚举类Class.getMethods()的成员( .

此外,反射对象可以在不授予共享者访问权限的情况下自由共享,因为在每次调用时都会进行访问检查。另一方面,共享方法句柄赋予共享者调用的能力。所以它们也有不同的安全含义。

方法句柄是一种用于查找、调整和调用方法的低级机制。虽然通过方法句柄调用比通过反射更快(尽管迄今为止,直接字节码调用通常仍然比方法句柄调用快),但方法句柄也更难使用,因为它们不会自动执行 Java 用户期望的适配(例如将 String 参数转换为 Object),导致链接错误。

反射库面向主流Java用户;方法句柄层更多地针对编译器和语言运行时编写者。选择专为这项工作设计的工具。

于 2015-06-06T02:48:08.283 回答
2

tl;博士不。您应该尽可能使用(并且更喜欢)MethodHandlesCore Reflection API。

MethodHandles.Lookup访问说(部分),

与每次调用反射方法时检查访问的核心反射 API 不同,方法句柄访问检查是在创建方法句柄时执行的

于 2015-06-06T00:37:21.980 回答