Java-7中的签名多态方法

13
据我所知,随着Java 7中MethodHandle的引入,编译器生成的方法重载也随之引入。
MethodHandle的javadoc(我已经删减了示例)说明如下:

Here are some examples of usage:

Object x, y; String s; int i;
mh = ...
// (Ljava/lang/String;CC)Ljava/lang/String;
// (String, char, char) -> String
s = (String) mh.invokeExact("daddy",'d','n');

// (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
// (Object, Object, Object) -> Object
x = mh.invokeExact((Object)1, (Object)2, (Object)3);

// (Ljava/util/List;)I
// (List) -> int
i = (int) mh.invokeExact(java.util.Arrays.asList(1,2,3));

// (Ljava/io/PrintStream;Ljava/lang/String;)V
// (PrintStream, String) -> void
mh.invokeExact(System.out, "Hello, world.");

Each of the above calls generates a single invokevirtual instruction with the name invoke and the type descriptors indicated in the comments. The argument types are taken directly from the actual arguments, while the return type is taken from the cast immediately applied to the call. This cast may be to a primitive. If it is missing, the type defaults to Object if the call occurs in a context which uses the return value. If the call occurs as a statement, a cast is impossible, and there is no return type; the call is void.

实际上,invokeExact和相关方法的行为就像每个可能的参数组合和返回类型都有一个重载一样。
我听说MethodHandles正在为Java 8中的lambda等功能做准备。(我知道它们已经对脚本语言很有用了。)
[/介绍]
那么,在Java中是否还有更多这些编译器生成的重载隐藏着?在未来会有更多的提示(比如扩展方法)吗?首先为什么需要它?仅仅是为了速度吗?它如何帮助lambda(我以为lambda会编译成匿名内部类)?
简而言之,它们(生成的重载)现在和将来为什么有用?
更新:我在这里所说的编译器生成的重载,Oracle的人称之为签名多态。
2个回答

16

我刚刚在Hotspot internals wiki上发现了一个有关MethodHandles和invokedynamic的页面。

它提出了一些有趣的观点,回答了以下问题(以及更多):

  • 在问题中所谓的“编译器生成的重载”,Java团队称之为签名多态性
  • MethodHandle.invokeExact等方法是唯一的签名多态方法
  • 在HotSpot VM上, MethodHandle.invoke * invokevirtual 字节码被秘密转换为 invokehandle 指令。
    • invokehandle类似于invokedynamic;一些内部细节不同,在每个invokedynamic指令必须指向自己的常量池缓存条目(CPCE)的地方,invokehandle可以共享CPCEs。
  • invokedynamic 在HotSpot VM上使用非公开的MethodHandle.invokeBasic
    • MethodHandle.invokeBasic类似于invokeExact,但更松散;例如,它不会检查调用点处的类型与被调用方的类型是否相同。
  • 热方法句柄(包括invokedynamic )可以进行JIT编译

此外,lambda表达式将通过invokedynamic实现。(从Edwin Dalorzo的回答中得知。)这意味着lambda表达式

  • 间接使用HotSpot VM上的MethodHandle.invokeBasic(参见上文),并且
  • 有资格进行JIT编译

4
这两个链接可能不能回答你所有的问题,但它们可能是一个很好的起点: 这是来自JDK 8中目前正在工作的专家小组的参考资料:项目Lambda。幸运的是,你可以在那里找到一些解释,特别是关于你对Lambda表达式作为内部类的误解。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接