jvm 字节码执行 (二)动态类型语言支持

动态类型语言 

  动态类型语言的关键特征是它的类型检查的主体过程是在运行期而不是编译期。

举例子解释“类型检查”,例如代码:

obj.println("hello world");

 假如这行代码是在Java语言中,并且变量obj的静态类型为java.io.PrintStream,那么变量obj的实际类型就必须是PrintStream的子类才是合法。否则,obj属于一个确实

有println(String)方法,单与PrintStream接口没有继承关系,代码依然不可能运行——因为类型检查不合法。是相同的代码在ECMAScript中情况不一样,无论obj是何种类型

只要这种类型的定义中确实包含有println(String)方法,那方法调用便可成功。

  这种差别产生的原因是Java语言在编译期已将println(String)方法完整的符号引用生成出来,作为方法调用指令参数存储到Class文件中,例如下面这段代码:

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

  这个符号引用包含了此方法定义在哪个具体类型之中、方法的名字以及参数顺序、参数类型和方法返回值等信息,通过这个符号引用,虚拟机可以翻译出这个方法的

直接引用。而在ECMAScript等动态类型语言中,变量obj本身是没有类型的,变量obj的值才是具有类型,编译时最多只能确定方法名称、参数、返回值这些信息,而不会

去确认方法所在的具体类型。“变量无类型而变量值才有类型”这个特点也是动态类型语言的一个重要特征。

  静态类型语言在编译期确定类型,最显著的好处是编译期可以提供严谨的类型检查,这样与类型相关的问题能在编码的时候就及时发现,利于稳定性及代码达到最大规模。

动态类型语言在运行期确定类型,这可以为开发人员提供更大的灵活性,某些在静态类型语言中需要大量“臃肿”代码来实现的功能,由动态类型语言来实现可能会更加清晰

简洁,清晰和简洁通常也意味着开发效率的提升。

java.lang.invoke包

  JDK1.7以前的字节码命令指令集中,4条方法调用指令(invokevirtual、invokespecial、invokestatic、invokeinterface)的第一个参数都是被调用的方法的符号引用,而

方法的符号引用在编译时产生,而动态类型语言只有在运行期。这样在Java虚拟机上实现的动态语言类型语言就不得不使用其他方式来实现。

java.lang.invoke包的主要目的是在之前单纯依靠符号引用来确定调用的目标方法这种方式以外,提供一种新的动态确定目标方法的机制,称为MethodHandle。

在拥有了Method Handle之后,Java语言也可以拥有类似函数指针或者委托的方法别名的工具了。

猜你喜欢

转载自www.cnblogs.com/jixp/p/10780951.html
今日推荐