执行引擎是跟操作系统相关的,.class都是JVM指令,JVM就是让执行引擎干活的命令。
执行引擎在执行java代码的时候都会有解释执行和编译执行两种选择。
解释执行:对源语言写成的源语句进行一句一句的翻译,翻译一句就提交给计算机执行一句,并不会形成目标程序。它的优点是翻译本身并不费事。它的缺点是运行速度慢,比如当程序中存在循环条件时,循环体内的语句就会被多次的翻译,从而影响运行速度
编译执行:现需要对源程序进行一个编译,生成一个目标文件,计算机再对这个目标程序进行执行。虽然这的编译的过程比上面提到的翻译的过程要复杂(通常要对代码进行语法分析,还要对代码进行优化,并分配内存,最后形成目标文件),但是一旦形成目标文件,就一劳永逸,不必再进行编译,所以执行速度较快
对于执行引擎来说,在活动线程中,只有位于栈顶的栈帧才是有效的,称为当前栈帧,执行引擎运行的所有字节码指令都是只针对当前栈帧进行操作。
下面讲一下方法调用:方法调用不等同于方法执行,唯一的任务就是确定被调用方法的版本,一切方法调用在class文件里面存储的只是符号引用,而不是方法在实际运行时内存布局中的入口地址。
解析:调用目标在程序代码写好,编译器运行时就必须确定下来,这类方法的调用称为解析,符合“编译期可知,运行期不可变”,及在解析阶段中能确定唯一版本。他们在类加载的时候就会把符号引用解析为该方法的直接引用。
主要包括:静态方法,私有方法,和被final修饰的方法,实例构造器,父类方法。
分派:分派分为静态分派和动态分派
静态分派:了解静态分派之前先熟悉两个概念静态类型和实际类型举例:
Human man = new Man();这里的Human就是静态类型,Man是实际类型。
public void sayHello(Human human){syso.peintln("hello human");}
public void sayHello(Man man){syso.peintln("hello man");}
obj.sayHello(man);输出结果:hello human
所有依赖静态类型来定位方法执行版本的分派动作成为静态分派,静态分派的典型应用是方法重载。
动态分配:
现在让man 重写父类的sayHello
@Override
public void sayHello(Man man){syso.peintln("hello man");}
man.sayHello();运行结果:hello man
在运行期间根基实际类型确定方法执行版本的分派过程称为动态分派,动态分派的典型类型是方法重写。