【问题标题】:Java 8 generic LambdaMetafactory?Java 8 通用 LambdaMetafactory?
【发布时间】:2015-01-28 16:02:18
【问题描述】:

在将Java 8 access private member with lambda?concrete format 转换为generic format 时,我发现another limitation

要发出完整的符号类型描述符,编译器还必须 确定返回类型。这是基于对方法的强制转换 调用表达式,如果有,否则为 Object 调用是表达式,否则如果调用是 声明。

我很好奇有没有办法overcome this

更新Working Example per Holger

【问题讨论】:

  • 当然。只需使用invoke 而不是invokeExact
  • 是的,它有效,谢谢@Holger。 invokeinvokeExact 是否引入了装箱/拆箱或性能惩罚
  • 这显然取决于 必需 转换,例如将ToIntFunction 转换为Object 不需要任何拳击。由于您只使用了一次MethodHandle,因此考虑性能是没有意义的;对于特定句柄,即使invokeExact 也会相当慢(与普通方法调用相比)。只有当你要经常调用相同的方法句柄时,你才可以考虑使用asType一次,这样你以后可以多次使用invokeExact,就像描述的here
  • 也许我应该强调 invoke签名多态 就像 invokeExact 一样,因此不需要装箱或可变参数处理,例如invokeWithArguments。不同之处在于invoke 允许 转换并将进行装箱/拆箱if requiredinvokeExact 要求调用类型签名和句柄的类型签名完全匹配。
  • 换句话说:一旦 LambdaMetafactory 拥有produced the lambda,在lambda usage 期间将不会有性能/装箱损失(除了 1 级间接),对吗? @Holger 请输入答案,我可以将其标记为完成。

标签: java generics lambda java-8


【解决方案1】:

如果您的编译时调用签名与您传递给LambdaMetafactoryinvokedType 参数不匹配,您可以使用invoke 而不是invokeExact。它将执行所需的转换。

对于 lambda 实例的方法的实际调用没有性能损失。在返回封装MethodHandleCallSite 之前,由LambdaMetafactory 决定生成的lambda 将如何工作。因此,调用它来构造 lambda 实例的方式不会影响结果。

【讨论】:

    猜你喜欢
    • 2015-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多