本文为笔记,来自《深入理解Java7》和网络技术文。
1)方法句柄method handle
对Java中方法、构造方法和域(getter|setter)的一个强类型的可执行的引用。通过方法句柄可以直接调用该句柄所引用的底层方法。对应java.lang.invoke.MethodHandle类。类点类似C/C++里面的函数指针。
2)类结构
在附件
3)使用方法句柄进行函数式编程
=>对数值进行操作:对数组中的每个元素依次执行某个操作
=>方法的柯里化:对一个方法的参数值进行预先设置之后,得到一个新的方法
4)MethodHandle VS Reflection
[转后再转,二次转,源为infoQ,http://blog.csdn.net/tobeandnottobe/article/details/7248164]
=>模拟方法调用层次:Reflection是在模拟Java代码层次的方法调用,而MethodHandle是在模拟字节码层次的方法调用。在MethodHandles.Lookup上的三个方法findStatic()、findVirtual()、findSpecial()正是为了对应于invokestatic、invokevirtual & invokeinterface和invokespecial这几条字节码指令的执行权限校验行为,而这些底层细节在使用Reflection API时是不需要关心的。
=>包含信息:Reflection中的java.lang.reflect.Method对象远比MethodHandle机制中的java.lang.invoke.MethodHandle对象所包含的信息来得多。前者是方法在Java一端的全面映像,包含了方法的签名、描述符以及方法属性表中各种属性的Java端表示方式,还包含有执行权限等的运行期信息。而后者仅仅包含着与执行该方法相关的信息。用开发人员通俗的话来讲,Reflection是重量级,而MethodHandle是轻量级,功能更强大、使用更灵活、性能更好。
=>优化:由于MethodHandle是对字节码的方法指令调用的模拟,那理论上虚拟机在这方面做的各种优化(如方法内联),在MethodHandle上也应当可以采用类似思路去支持(但目前实现还不完善)。而通过反射去调用方法则不行。
=>设计目标服务对象:Reflection API的设计目标是只为Java语言服务的,而MethodHandle则设计为可服务于所有Java虚拟机之上的语言,其中也包括了Java语言而已。
5)invokedynamic指令
http://han.guokai.blog.163.com/blog/static/13671827120118125237946/暂时不怎么懂
invokedynamic指令用于支持非Java语言,尤其是动态语言,目前Java编译器不能自动生成invokedynamic指令。
=>Invokedynamic指令将“链接”延迟到运行时才执行,本来是在编译时完成的。是通过“使运行时系统能够自定义调用点和方法实现之间的连接”来实现的。动态调用的调用点通过引导方法连接到一个方法上,这个引导方法是由动态语言编译器指定的,并被JVM调用一次来连接到位置上。
=>动态调用指令简化并潜在改善了JVM上动态语言的编译器和运行时系统的实现。动态调用指令是通过允许语言实现者自定义连接行为做到这点的。这是和其它JVM指令对比而言的,如虚调用指令(invokevirtual)的连接行为是特定于Java类和接口的,是由JVM硬连接的。
=>每个动态调用指令(invokedynamic instruction)的实例被称为一个动态调用点(dynamic call site)。一个动态调用点最初是未连接的状态,表示这个调用点没有指定可调用的方法。如前面所述,动态调用点通过引导方法连接到一个方法上。引导方法是由动态语言编译器所指定的方法,并被JVM调用一次来连接到位置上。引导方法返回的对象持久地决定了调用点的行为。
=>使用动态调用指令调用动态链接方法步骤:①定义引导方法;②指定常量池条目;③使用动态连接指令
【补充】:
静态类型语言:在编译时进行类型检查的语言。
动态类型语言:在运行时进行类型检查的语言。
强类型语言:对其要操作的值的类型有特定的限制,可防止参数类型不对的操作执行。
弱类型语言:会隐式地对错误或不兼容类型的操作参数进行转换。