【问题标题】:invokedynamic and implicit methods调用动态和隐式方法
【发布时间】:2023-03-15 21:31:01
【问题描述】:

正如我从阅读this 帖子中了解到的,关于 JDK 7 中新的 invokedynamic 字节码指令,它可以调用对象类中未静态定义的对象的方法,并将这些方法调用解析为通过拦截方法调用目标解析在其他一些类中实现具体的静态方法(帖子给出了一个例子)。

这是否意味着 Java 7 类可以像 Scala 一样具有隐式方法?如果不是,Scala 中的隐式方法解析与 invokedynamic 方法解析有何不同?

【问题讨论】:

    标签: java scala java-7 invokedynamic implicit-methods


    【解决方案1】:

    完全不相关。 scala 中的隐含在编译时完全解析。编译器会插入一些您也可以自己编写的内容。如果它不能做到这一点,在编译时,就会出现错误。 InvokeDynamic 是关于在运行时查找方法,如果找不到则在运行时失败。

    具体来说,如果你在 scala x.m() 中编写类型 x 中没有方法 m 的地方,它会寻找一个隐式转换,即一个函数,比如说 f,它在作用域内(你可以在这里调用 f点),标记为implicit,它将接受x作为参数,其结果类型有一个方法m(规则中有很多细节,但这就是本质)。如果它找到这样的方法,那么它将用正确键入的f(x).m() 替换x.m()。它也可以在代码中以这种方式编写,并且必须在 java 中编写。如果找不到这样的函数 f,则存在编译时错误。

    如果您调用g(x) 并且x 不是传递给g 的正确类型,也会发生同样的情况。如果有一个函数f 使得f(x) 具有正确的类型,那么它将用g(f(x)) 替换代码。再一次,你可以用普通的 scala 自己编写,同样,如果没有这样的方法,它将无法编译。

    Dynamic 就是在编译时不用过多担心x 中是否有m 方法,并在运行时寻找。这就是像 JRuby 或 Groovy 这样的动态语言通常的工作方式。 scala 中有一些相关的东西,trait Dynamic(标记为实验性的)。

    【讨论】:

    • 那么invokedynamic不能给Java类添加动态方法?
    • 主要是字节码的变化(如果我阅读了您正确链接的帖子,更像是一个巧妙的语义技巧),其主要目标是简化 JVM 上动态语言的实现.在 java 中允许动态调用(绝对不是动态语言)是一个不同的问题。如果他们选择这样做,InvokeDynamic 会提高效率。但是这样的事情已经可以在语言级别实现,因为在 VM 中可以使用反射。
    • 快速浏览了 JSR,听起来它确实可以在 java 中提供动态调用(如果我理解正确,可能会在没有运行时检查的情况下将引用转换为 Dynamic,并且调用在编译器视为 Dynamic 的 ref 上是动态的)。尽管如此,这与 scala 的隐式完全没有关系。
    • @didierd 根据 [1],java.dyn.Dynamic 接口并没有使其成为 Java 语言。相反,应该使用java.lang.invoke.MethodHandle 进行反射调用,以从Java 获取invokedynamic 字节码。 Scala 的 Dynamic 特征基本上是 java.dyn.Dynamic 应该是的。参考:[1]stackoverflow.com/questions/7031634/…
    • @Kipton 感谢您提供此信息。
    【解决方案2】:

    invokedynamic 字节码将有助于加速 JVM 上的动态语言。它还将加快对 Scala 中结构类型的访问。 invokedynamic 的替代方案(也是 JDK 7 之前的唯一选项)是反射,它真的很慢。

    Java 语言是静态类型的,不具有使用 invokedynamic 的功能(除了使用 java.lang.invoke.MethodHandle 的显式反射方法调用,根据 this question)。

    Scala 隐式实际上是静态解析的,因此与调用动态无关。有关其工作原理的详细信息,请参阅 Daniel Sobral 的精彩曝光:Where does Scala look for implicits?

    【讨论】:

      猜你喜欢
      • 2012-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-20
      • 1970-01-01
      相关资源
      最近更新 更多