据我在阅读this帖子中了解JDK 7中新的invokedynamic字节码指令时,它可以调用对象类中没有静态定义的对象上的方法,并且可以解析这些方法调用通过拦截方法调用目标分辨率来解决其他类中的一些具体静态方法(帖子给出了一个例子)。
这是否意味着Java 7类可以使用Scala之类的隐式方法?如果不是,Scala中的隐式方法解析与invokedynamic方法解析有何不同?
答案 0 :(得分:13)
完全不相关。 scala中的 Implicits 在编译时完全解析。编译器会插入您自己编写的内容。如果它不能这样做,在编译时,就会出错。 InvokeDynamic是在运行时查找方法,如果找不到则在运行时失败。
具体来说,如果你在scala x.m()
中写入x类型中没有方法m,它将寻找一个隐式转换,即一个函数,比如f,它在范围内(你可以调用f此时),标记为隐式,它将接受x作为参数,其结果类型具有方法m
(规则中有更多细节,但这是本质)。如果找到这样的方法,那么它将用正确键入的x.m()
替换f(x).m()
。它也可以在代码中以这种方式编写,并且必须在java中编写。如果找不到这样的函数f,则存在编译时错误。
如果您致电g(x)
并且x
不是传递给g
的正确类型,则会发生相同的情况。如果有f
函数使f(x)
具有正确的类型,那么它将用g(f(x))
替换代码。再一次,你可以用普通的scala写自己,再说一次,如果没有这样的方法,它就不会编译。
动态是在编译时不要过于担心m
中是否存在x
方法,并且在运行时查找一个方法。这就像JRuby或Groovy这样的动态语言通常如何工作。 scala中有一些相关的东西,特性动态(标记实验)。
答案 1 :(得分:5)
invokedynamic字节码有助于加速JVM上的动态语言。它还将加速对Scala中结构类型的访问。 invokedynamic(以及JDK 7之前的唯一选项)的替代方法是反射,这非常慢。
Java-the-language是静态类型的,并且没有使用invokedynamic的功能(除了使用java.lang.invoke.MethodHandle的显式反射方法调用,根据this question)。
Scala implicits实际上是静态解析的,因此与invokedynamic无关。有关其工作原理的详细信息,请参阅Daniel Sobral的优秀曝光:Where does Scala look for implicits?