java虚拟机动态类型语言支持
来源:互联网 发布:tvb软件下载 编辑:程序博客网 时间:2024/06/07 06:00
这篇博客是根据《深入理解java虚拟机》的讲解和本人对动态类型语言的一些认识,来深度剖析一下java虚拟机对动态类型语言的支持!
(一)什么是动态类型语言
在讲解java虚拟机对动态类型语言支持之前,我们首先要弄明白动态类型语言是什么?它与java语言、java虚拟机有什么关系?
那么接下来先回答第一个问题,什么是动态类型语言:动态类型语言的关键特征是它的类型检查的主体过程是在运行期而不是编译器,
满足这个特征的语言有很多,常用的包括: APL、JavaScript、python、Ruby、Groovy等。相对的在编译期就进行类型检查过程的
语言(C++和Java等)就是最常用的静态类型语言。大家可能对上面定义过于概念化,那我们不妨通过几个例子以最浅显的方式说明
什么是“在编译器/运行期进行”和什么是“类型检查”。首先看下面这段简单的Java代码:它是否能正常编译和运行呢?
public static void main(String[] args) {int i = 10;int j = 0;int v = i/j;}
这段代码相信大家再熟悉不过了,它可以正常编译,但是会运行时会报ArithmeticException异常。在Java虚拟机中规范中明确规定了
ArithmeticException是一个运行异常,通俗一点说,运行时异常只要代码不运行到这一行就不会有问题。与运行异常相对应的是编译时
异常,接下来看一下编译时异常的例子:
public static void main(String[] args) { FileInputStream fis = null; fis = new FileInputStream("test.txt"); }
上面这个例子中 fis = new FileInputStream("test.txt")会抛出IOException异常,这是一个编译时异常,如果不做try-catch处理,
编译都通不过。通过上面两个例子就是想说明有些检查是在运行期进行的,有些检查是在编译器进行的。
接下来再举一个例子来解释“类型检查”,例如下面这一句非常简单的代码:
obj = Demo(); obj.function();
上面代码中假设Demo是一个类,且里面有function方法,这两行对于Java说,相信大家都知道是无法编译的更别提执行了。
但是类似的代码在JavaScript或者Python中情况则不一样,是可以编译并且可以执行的。这种差别产生的原因在于动态类型语言中,
变量obj本身是没有类型的,变量obj的值才具有类型,这是因为动态类型语言在运行期确定类型的,而Java或者静态类型语言是
编译器确定类型的。孰好孰坏不知道,应该是各有所长吧。
(二)JDK1.7与动态类型
在介绍完动态类型,回到Java语言、虚拟机和动态类型语言之间的关系。其实Java虚拟机层面对动态类型语言的支持一直都有所欠缺,
主要表现在方法调用方面:JDK1.7以前的字节码指令集中,4条方法调用指令(invokevirtual , invokespecial , invokestatic ,
invokeinterface)的第一条参数都是被调用的方法的符号引用,前面已经提到过,方法的符号引用在编译时产生,而动态类型语言
是在动态运行期才能确定接受者的类型。因此这也就是JDK1.7中invokedynamic指令以及java.lang.invoke包出现要解决的问题。
(1)java.lang.invoke包
void sort(int list[], const int size , int (*compare)(int, int))
但Java语言就做不到这点,即没有办法把一个函数作为参数进行传递。普遍的做法是设计一个带有compare()方法的Comparator接口,
package demo;import java.lang.invoke.MethodHandle;import java.lang.invoke.MethodType;import static java.lang.invoke.MethodHandles.lookup;public class MethodHandleTest {static class ClassA{public void println(String s){System.out.println(s);}}public static void main(String[] args) throws Throwable {Object obj = System.currentTimeMillis() % 2 == 0 ? System.out : new ClassA();//无论obj最终是哪个实现类,下面这句都能正确调用到println方法getPrintlnMH(obj).invokeExact("test");}private static MethodHandle getPrintlnMH(Object reveiver) throws Throwable{//MethodType: 代表"方法类型",包含了方法的返回值(methodType()的第一个参数)和具体参数(methodType()第二个及以后的参数)MethodType mt = MethodType.methodType(void.class,String.class);//lookup()方法来自于MethodHandles.lookup,这句的作用是在指定类中查找符合给定的方法名称、方法类型、并且符合调用权限的方法语柄/*因为这里调用的是一个虚方法,按照Java语言的规则,方法第一个参数是隐式的,代表该方法的接受者,也即是this指向的对象,这个参数以前是放在 参数列表中进行传递的,而现在提供了bindTo方法来完成这件事情*/return lookup().findVirtual(reveiver.getClass(),"println",mt).bindTo(reveiver);}}实际上,方法getPrintlnMH()中模拟了invokevirt指令的执行过程,只不过它的分派逻辑并非固化在Class字节码上,而是通过一个具体
- java虚拟机动态类型语言支持
- 人物专访:Java虚拟机的动态语言支持
- 介绍JDK 动态类型语言支持
- 动态类型的语言支持--invokedynamic
- Java语言的动态性支持
- 解析JDK 7的动态类型语言支持
- 执行篇:解析JDK 7的动态类型语言支持
- Xen 支持的虚拟机类型
- 动态类型语言&动态语言
- Java 编程语言支持三种循环构造类型
- 微软在动态语言支持上超越了Java?
- .NET和Java将有更好的动态语言支持
- 微软在动态语言支持上超越了Java?
- 微软在动态语言支持上超越了Java?
- Java语言的动态性支持(一)ScriptEngineManager
- Java语言的动态性支持(二)reflection反射
- 动态类型强类型语言
- JAVA 虚拟机 [ 类型生命周期 ]
- WinForm中button禁用点击的另一种实现
- 10年磨一剑,编程经验总结。
- jQuery 的选择器
- JDK 1.8 新特性记录
- 跨越解决方案之nginx
- java虚拟机动态类型语言支持
- 二位数组中的查找——剑指offer
- mongodb 使用$lookup做多表关联处理
- 搜狐笔试Kolakoski数列
- python numpy格式化打印
- Xshell中输入rz提示:-bash: rz: command not found
- 命令模式
- hbase全分布安装出现的问题
- 想要将PDF文件中的水印进行去除如何操作