TL;博士
请提供一段用一些众所周知的动态语言(例如 JavaScript)编写的代码,以及该代码在使用 invokedynamic 的 Java 字节码中的样子,并解释为什么使用 invokedynamic 是向前迈出的一步。
背景
我已经用谷歌搜索并阅读了很多关于不再是新的调用动态指令的信息,互联网上的每个人都同意它有助于加速 JVM 上的动态语言。感谢 stackoverflow,我设法让我自己的字节码指令与 Sable/Jasmin 一起运行。
我已经了解 invokedynamic 对于惰性常量很有用,我还认为我了解OpenJDK 如何利用 invokedynamic 进行 lambdas。
Oracle有一个小例子,但据我所知,在这种情况下使用invokedynamic会破坏目的,因为“加法器”的例子可能更简单、更快,并且效果与以下字节码表达的效果大致相同:
aload whereeverAIs
checkcast java/lang/Integer
aload whereeverBIs
checkcast java/lang/Integer
invokestatic IntegerOps/adder(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;
因为由于某种原因,Oracle 的引导方法知道两个参数都是整数。他们甚至“承认”:
[..] 它假定参数 [..] 将是 Integer 对象。如果引导方法的参数(在本例中为 callerClass、dynMethodName 和 dynMethodType)不同,则引导方法需要额外的代码来正确链接 invokedynamic [..]。
好吧,是的,如果没有那个有趣的“附加代码”,那么在这里使用 invokedynamic 是没有意义的,是吗?
因此,在那之后以及一些进一步的 Javadoc 和博客条目之后,我认为我已经很好地掌握了如何使用 invokedynamic 作为一个糟糕的替代品,而 invokestatic/invokevirtual/invokevirtual 或 getfield 也可以正常工作。
现在我很好奇如何将invokedynamic指令实际应用到现实世界的用例中,以便它实际上是对“传统”调用的一些改进(除了惰性常量,我得到了那些......)。