调用动态和隐式方法

发布于 2024-11-30 12:00:22 字数 267 浏览 0 评论 0原文

据我了解,阅读这篇关于新invokedynamic的文章JDK 7 中的字节码指令,它使得可以调用对象类中未静态定义的对象的方法,并通过拦截方法调用目标解析(帖子给出一个例子)。

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

As I understand from reading this post about the new invokedynamic bytecode instruction in JDK 7, it makes it possible to call methods on the objects which are not statically defined in the object's class and have those method calls be resolved to some concrete static methods in some other class by intercepting the method call target resolution (the post gives an example).

Does this mean that Java 7 classes can have implicit methods like Scala has? If not how is implicit method resolution in Scala different from the invokedynamic method resolution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

私藏温柔 2024-12-07 12:00:22

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

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

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

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

It is completely unrelated. Implicits in scala are fully resolved at compile time. The compiler inserts something that you could as well have written yourself. If it cannot do that, at compile time, there is an error. InvokeDynamic is about finding the method at runtime and failing at runtime if it cannot be found.

Specifically, if you write in scala x.m() where there is no method m in type x, it will look for an implicit conversion, that is a function, say f, which is in scope (you could call f at this point), which is marked as implicit, which will accept x as a parameter, and whose result type has a method m (there are a lot more details in the rules, but this is the essence). If it finds such a method, then it will replace x.m() by the properly typed f(x).m(). It could just as well have been written that way in the code, and it would have to in java. If no such function f can be found, then there is a compile time error.

It happens just the same way if you call g(x) and x is not of the right type to be passed to g. If there is a function f such that f(x) has the proper type, then it will replace the code by g(f(x)). Again, you could have written that yourself in plain scala, and again, if there is no such method, it will not compile.

Dynamic is about not worrying too much at compile time whether there is an m method in x, and looking for one at runtime. This is how a dynamic language like JRuby or Groovy typically works. There is something related in scala, trait Dynamic (marked experimental).

勿挽旧人 2024-12-07 12:00:22

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

Java 语言是静态类型的,并且不具有使用 invokedynamic 的功能(除了使用 java.lang.invoke.MethodHandle,根据 这个问题)。

Scala 隐式实际上是静态解析的,因此与 invokedynamic 无关。有关其工作原理的详细信息,请参阅 Daniel Sobral 的精彩揭露:Scala 在哪里寻找隐式?

The invokedynamic bytecode will help speed up dynamic languages on the JVM. It will also speed up accesses to structural types in Scala. The alternative to invokedynamic (and only option prior to JDK 7) is reflection, which is really slow.

Java-the-language is statically typed, and doesn't have features that use invokedynamic (apart from explicit reflective method calls using java.lang.invoke.MethodHandle, according to this question).

Scala implicits are actually statically resolved, and thus unrelated to invokedynamic. For details about how it works, see Daniel Sobral's excellent expose: Where does Scala look for implicits?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文