前言

上一节讲述了栈桢和分派的细节,这一节咱们来讲讲自java语言诞生新减少的新语言个性:动静类型语言反对,这一节将会依据动静语言的个性以及相干的介绍同时讲述jvm一个重要的指令:invoke dynamic指令。然而须要留神的是:invokedy namic指令面向 的次要服务对象并非Java语言,而是其余Java虚拟机之上的其余动静类型语言

概述

  1. 介绍什么是动静类型语言,以及java为什么是动态语言的解说。
  2. 介绍invokeDynamic指令在理论案例中的使用
  3. 介绍java实现动静语言调用的一些曲线救国的伎俩。

动静类型语言

什么是动静类型语言

动静类型语言的要害特色是它的类型查看的主体过程是在运行期而不是编译期。而java就是典型的动态类型语言,须要在编码的过程中确定的,动态的语言也意味着所有的类型在编译器必须确定。

为什么java是动态类型?

这里牵扯到一个问题就是为什么java是动态类型呢?咱们能够看一下invokeVitual命令,这个命令依据如下的内容,确定一个属性的全类名,以及类型,在符号援用的阶段能够看到根本的内容:

invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

这些符号援用在翻译为间接援用是须要确切的类型的,所以在晚期的java天生不足动静语言的反对。

动静语言类型反对

java在jdk7之后退出了动静语言反对,对于退出动静语言类型的反对外围是应用invoke dynamic命令, 这种形式应用了相似曲线救国的形式,也是为兼容思考不得不做的一种斗争,比方最常见的类型数组,在java中咱们必须声明确数组寄存的类型,而jdk引入了invokeDynamic这个指令之后,就能够实现对于一个办法参数的动静调用。

动静类型语言是能够让对象的类型能够在运行时候再确定,比方JS和Python的var。

invokedynamic指令

上面来说下invoke这个指令是如何实现动静类型语言的,在java中是无奈把一个函数作为参数传递的,更多的形式应用相似实现接口的形式进行解决,而新的指令在某种程度上是应用相似MethodHandle的形式进行解决的,MethodHandle是对通过字节码的办法指令调用的模仿,但和反射不同的是反射是基于Java语言服务的,而MethodHandler则是服务于所有虚拟机上的一种语言。

每一处含有invokedynamic指令的地位都被称作“动静调用点(Dynamically-Computed Call Site)”, 这条指令的第一个参数不再是代表办法符号援用的CONSTANT_Methodref_info常量,而是变为JDK 7 时新退出的CONSTANT_InvokeDynamic_info常量,从这个新常量中能够失去3项信息:疏导办法 (Bootstrap Method,该办法寄存在新增的BootstrapMethods属性中)、办法类型(MethodType)和 名称

为了更好的了解这个命令,上面咱们来看下理论运行过程当中的利用,比方在jdk8中引入的lambada表达式和默认办法就是通过invokedynamic命令实现的,然而应用jdk8的实现看起来比拟难以了解,上面来看一下书中给的一段案例代码:

Constant pool:#121 = NameAndType #33:#30 // testMethod:(Ljava/lang/String;)V #123 = InvokeDynamic #0:#121 // #0:testMethod:(Ljava/lang/String;)Vpublic static void main(java.lang.String[]) throws java.lang.Throwable; Code:stack=2, locals=1, args_size=10: ldc #23 // String abc2: invokedynamic #123, 0 // InvokeDynamic #0:testMethod: (Ljava/lang/String;)V 7: nop8: returnpublic static java.lang.invoke.CallSite BootstrapMethod(java.lang.invoke.Method Handles$Lookup, java.lang.Strin Code:    stack=6, locals=3, args_size=30: new3: dup4: aload_05: ldc7: aload_18: aload_29: invokevirtual #6512: invokespecial #71 15: areturn#63#1// class java/lang/invoke/ConstantCallSite// class org/fenixsoft/InvokeDynamicTest// Method java/lang/invoke/MethodHandles$ Lookup.findStatic:(Ljava/lang/Cl // Method java/lang/invoke/ConstantCallSite. "<init>":(Ljava/lang/invoke/M 

从下面的办法调用能够看到,应用的是invokeDynamic的调用指令以及参数为第123项的常量,比方如下的内容:

2: invokedynamic #123, 0 // InvokeDynamic #0:testMethod:(Ljava/lang/String;)V

而BootstrapMethod()办法中指令将会产生testMethod()办法,当然这个办法在java源码中是看不见的,而是由invokeDynamic动静生成的一个办法,当指令实现对应的办法调用之后,这个指令的调用过程也宣告完结了。

总结

本文的内容比拟啊间断,次要针对动静类型语言做了一个补充,内容比拟剪短,至此,jvm的内容大抵以及全副讲述结束,而对于书中的最初一节并发编程的形容,集体将会放到《并发编程实战》中进行总结(又得回去看一遍)。

写在最初

invokeDynamic次要服务的是其余语言的接入,然而从实际效果来看不是非常的现实。