Mic*_*uff 11 java-7 java-8 methodhandle
据我所知,随着Java 7中MethodHandle的引入,引入了编译器生成的方法重载.
MethodHandle的javadoc状态(我已经修剪了示例):
以下是一些用法示例:
Run Code Online (Sandbox Code Playgroud)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指令,其名称为invoke,注释中指示的类型描述符.参数类型直接取自实际参数,而返回类型取自立即应用于调用的强制转换.这个演员可能是一个原始人.如果缺少,则如果在使用返回值的上下文中发生调用,则类型默认为Object.如果调用作为语句发生,则转换是不可能的,并且没有返回类型; 电话无效.
实际上,invokeExact和friends的行为就好像每个可能的参数组合和返回类型都有重载.
我听说MethodHandles正在为Java 8中的功能做准备,比如lambdas.(我知道它们对脚本语言已经很有用了.)
[/介绍]
那么,是否有更多这些编译器生成的重载隐藏在Java中?是否有提示将来会有更多这些提示(例如,使用扩展方法)?为什么首先需要它?仅速度?它如何帮助lambdas(我认为lambdas会编译成一个匿名的内部类)?
简而言之,理由是什么; 为什么它们(生成的重载)现在和将来都有用?
更新:我在这里称之为编译器生成的重载,Oracle人称之为签名多态.
Mic*_*uff 12
我刚在MethodHandles和invokedynamic上遇到过Hotspot internals wiki
它提出了一些有趣的观点来回答这些问题(以及其他一些问题).
MethodHandle.invokeExact
和朋友是独一无二的,是唯一的签名多态方法.invokevirtual
MethodHandle.invoke*的字节码被秘密转换为invokehandle
指令.
invokehandle
就像invokedynamic
; 一些内部结构是不同的,并且每个invokedynamic
指令必须指向它自己的常量池缓存条目(CPCE),invokehandle
s可以共享CPCE.invokedynamic
MethodHandle.invokeBasic
在HotSpot VM上
使用非公共MethodHandle.invokeBasic
就像invokeExact但更松散; 例如,它不会检查呼叫站点的类型与被叫方的类型.invokedynamic
)可以进行JIT编译另外,lambda表达式将通过实现invokedynamic
.(来自Edwin Dalorzo的回答.)这意味着lambda表达式
MethodHandle.invokeBasic
HotSpot VM(见上文),和 归档时间: |
|
查看次数: |
2079 次 |
最近记录: |