当 MethodHandle 更快时,为什么要使用反射来访问类成员?

2023-12-28

随着 Java 7 的发布,MethodHandle https://docs.oracle.com/javase/8/docs/api/java/lang/invoke/MethodHandle.html,它允许用户像使用其底层字节码一样调用方法。特别是,MethodHandles.Lookup https://docs.oracle.com/javase/8/docs/api/java/lang/invoke/MethodHandles.Lookup.html类提供工厂方法来创建方法句柄来访问类成员:

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

从功能上讲,这或多或少相当于使用反射来访问这些相同的类成员,但是方法句柄比反射更快 https://stackoverflow.com/a/22337726/1247781.

那么,是否有任何理由仍然使用反射功能,例如Field#get(..) http://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Field.html/Method.invoke(..) http://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Method.html或者随着更快的方法句柄的引入,这些方法实际上已经过时了吗?

Note that while method handles were introduced in Java 7, my question primarily pertains to Java 8, in which they were optimized to supposedly reach performance approximately equal to direct field/method calls, surpassing reflection's ability.


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

反射是一种通用的自省机制,它包括方法句柄机制所缺乏的许多功能,例如枚举类的成员(Class.getMethods()),检查成员的特征,例如其可访问性标志,检查成员的通用签名等。

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当 MethodHandle 更快时,为什么要使用反射来访问类成员? 的相关文章

随机推荐