当前位置: 首页 > 知识库问答 >
问题:

为什么在MethodHandle更快的情况下使用反射访问类成员?

凌经赋
2023-03-14

随着Java7的发布,出现了methodhandle,它允许用户像使用底层字节码一样调用方法。特别是,MethodHandles.lookup类提供工厂方法来创建方法句柄以访问类成员:

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

那么,有没有理由仍然使用像字段#get(..)/方法.invoke(..)这样的反射功能,或者这些方法由于引入了更快的方法句柄而实际上已经过时了?

注意,虽然方法句柄是在Java7中引入的,但我的问题主要与Java8有关,在Java8中,方法句柄进行了优化,以达到大约等于直接字段/方法调用的性能,超过了反射的能力。

共有1个答案

尉迟明贤
2023-03-14

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

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

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

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

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

 类似资料:
  • 问题内容: 因此,通过阅读一些文章,我得到的信息是能够实时修改字段并为类设置值,而无需重新编译。 所以有可能对没有源代码的第三方Java库创建的类执行此操作/是否可以在运行时使用反射来修改类实例? 在其他哪些情况下,通常还会使用反射? 我试图了解反射如何适用。 问题答案: 任何时候您在运行时处理字符串,并希望将该字符串的一部分视为语言中的标识符。 远程过程调用-将通过网络接收的消息的一部分视为方法

  • 4如果类成员访问中的id-expression是窗体的限定id-id 首先在对象表达式([class.member.lookup])的类中查找或运算符后面的,如果找到,则使用名称。否则,它将在整个后缀表达式的上下文中查找。 因此,首先必须在struct中查看,但在那里是不明确的。事实上,Clang报告了一个错误:

  • 我的问题是为什么找不到“name”字段?

  • 本文向大家介绍请问在什么情况下回使用assert?相关面试题,主要包含被问及请问在什么情况下回使用assert?时的应答技巧和注意事项,需要的朋友参考一下 考察点:JAVA 调试 assertion (断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个 boolean表达式进行检查,一个正确程序必须保证这个boolea

  • 在“Kotlin in Action”中,它说“如果一个成员属性引用了Person类的年龄属性,memberProperty.get(person)是一种动态获取person.age值的方法”,代码为(10.2.1 Kotlin Reflection API): 我不明白为什么这个例子提到“动态”获取属性的值。当我运行以下代码时,它才起作用: 是否有其他成员属性反射的案例或示例?

  • 问题内容: 我需要创建一个使用12个参数的存储过程,并使用此参数的不同组合来过滤查询。所有12个参数都不是强制性的,好像我传递3或5或12个参数取决于用户输入的搜索输入。 我可以使用动态SQL查询或“ Case where”语句创建2种方法。这些查询的示例如下: 动态查询 DECLARE @condition VARCHAR(MAX)=’‘ Declare @var1 varchar(10) De