invokedynamic和隐式方法

正如我在阅读这篇关于JDK 7中新的invokedynamic字节码指令的post所理解的那样,它可以调用对象类中没有静态定义的对象上的方法,并将这些方法调用解析为某些具体的静态方法。其他类通过拦截方法调用目标分辨率(post给出一个例子)。

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

这完全不相关。 scala中的Implicits编译时完全解析 。 编译器会插入您自己编写的内容。 如果它不能这样做,在编译时,就会出错。 InvokeDynamic是在运行时查找方法,如果找不到则在运行时失败。

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

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

动态是在编译时不要过于担心x是否有m方法,并且在运行时查找一个方法。 这就像JRuby或Groovy这样的动态语言通常如何工作。 scala中有一些相关的东西,特性动态(标记实验)。

invokedynamic字节码将有助于加速JVM上的动态语言。 它还将加速对Scala中结构类型的访问。 invokedynamic(以及JDK 7之前的唯一选项)的替代方法是reflection,这非常慢。

Java-the-language是静态类型的,并且没有使用invokedynamic的function(除了使用java.lang.invoke.MethodHandle的显式reflection方法调用,根据这个问题 )。

Scala implicits实际上是静态解析的,因此与invokedynamic无关。 有关它如何工作的详细信息,请参阅Daniel Sobral的优秀曝光: Scala在哪里寻找暗示?

Interesting Posts