关于Java-7中的签名多态方法

问题描述 投票:0回答:2

据我所知,随着 Java 7 中 MethodHandle 的引入,也引入了编译器生成的方法重载。

MethodHandlejavadoc 指出(我已经修剪了示例):

以下是一些用法示例:

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.");

上述每个调用都会生成一条invokevirtual指令 与名称调用和类型描述符中指示 评论。参数类型直接取自实际 参数,而返回类型立即从强制转换中获取 应用于通话。此转换可能是原始的。如果是的话 缺少,如果调用发生在上下文中,则类型默认为 Object 它使用返回值。如果调用作为语句发生,则强制转换 不可能,并且没有返回类型;通话无效。

实际上,invokeExact 和朋友的行为就好像参数和返回类型的每种可能组合都存在重载。

我听说 MethodHandles 正在为 Java 8 中的功能(如 lambda)做准备。 (我知道它们对于脚本语言已经很有用了。)

[/介绍]

那么,Java 中是否隐藏着更多编译器生成的重载?是否有迹象表明将来会有更多(例如,使用扩展方法)?首先为什么有必要?仅仅是速度吗?它如何帮助 lambda 摆脱困境(我以为 lambda 会编译为匿名内部类)?

简而言之,理由是什么;为什么它们(生成的重载)现在和将来有用?

更新:我所说的编译器生成在这里重载,Oracle人员称之为签名多态

java-7 java-8 methodhandle
2个回答
16
投票

我刚刚在 MethodHandles 和 invokedynamic

上发现了一个 Hotspot 内部 wiki

它提出了一些有趣的观点来回答这些问题(以及更多问题)。

  • 问题中所谓的编译器生成的重载,java 人称之为签名多态。
  • MethodHandle.invokeExact
    和朋友是独一无二的,是唯一的签名多态方法。
  • 在 HotSpot VM 上,MethodHandle.invoke* 的
    invokevirtual
    字节码被秘密转换为
    invokehandle
    指令。
  • invokehandle
    就像
    invokedynamic
    ;一些内部结构有所不同,每个
    invokedynamic
    指令必须指向它自己的常量池缓存条目 (CPCE),
    invokehandle
    可以共享 CPCE。
  • invokedynamic
    在 HotSpot VM 上使用非公开
    MethodHandle.invokeBasic
  • MethodHandle.invokeBasic
    类似于 invokeExact 但更宽松;首先,它不会检查调用站点的类型与被调用者的类型。
  • 热方法句柄(包括
    invokedynamic
    )可以进行 JIT 编译

此外,lambda表达式将通过invokedynamic

实现。 (从 Edwin Dalorzo 的回答中得到的。)这意味着 lambda 表达式

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

4
投票
这两个链接可能无法回答您的所有问题,但它们可能是一个很好的起点:

  • Lambda 表达式的翻译
  • 从 Lambda 到字节码
这是来自目前从事 JDK 8:Project Lambda 的专家组的参考资料。幸运的是,您可以在那里找到一些解释,最重要的是关于您对 lambda 表达式作为内部类的误解。

© www.soinside.com 2019 - 2024. All rights reserved.