静态分派与动态分派
1、多态和重载的区别
多态:是一个接口的多种实现,分为类的多态和函数的多态
函数的多态性:一个函数被定义为多个参数(重载)
类的多态:在基类的函数前加上virtual关键字(虚函数),在派生类中重写该函数(是重写该函数!!!),运行时将会根据对象的实际类型来调用相应的函数。
重载中的静态分派:Human man = new Man(); Human为静态类型,Man为实际类型;
变量本身的静态类型不会变化,静态类型在编译器是可知的;实际类型的变化结果在运行期才会知道;编译器在编译程序的时候并不知道一个对象的实际类型是什么。
JVM中编译器,在重载时,通过参数的静态类型而不是实际类型作为判定的依据。
2、静态分派
所有依赖静态类型来定位方法执行版本的分派动作成为静态分派。
静态分派的典型应用是方法重载。
静态分派发生在编译阶段,因此确定静态分派的动作实际上不是由虚拟机来执行的。
重载的版本并不是唯一的。例如char类型,如果没有这个类型参数,可以调用int类型,,,
自动类型转换按照char->int->long->float->double的顺序进行。
3、动态分派
重写(Override):在运行期根据实际类型确定方法执行版本的分派过程称为动态分派。
常量池中的符号引用?
invokevirtual指令的多态查找过程:
1)找到操作数栈顶的第一个元素所指向的对象的实际类型,记作C
2)如果在类型C中找到与常量中的描述符和简单名称都相符的方法,则进行访问权限校验。如果校验通过返回这个方法的直接引用,查找过程结束;如果不通过,返回java.lang.IllegalAccessError异常
3)否则,按照继承关系,从下往上一次对C的各个父类进行第2步的搜索和验证过程
4)如果始终没有找到合适的方法,则抛出java.lang.AbstractMethodError异常
Java的静态分派属于多分派类型,动态分派类型属于但分派类型。
4、动态类型语言
动态类型语言的关键特征是它的类型检查的主体过程是在运行期而不是编译器。
运行时异常通俗的来讲,就是代码不运行到这一行就不会有问题。
Public static void main(String[] args) {
Int[][][] array = new int[1][0][-1];
}
能够正常编译,但是运行时会报错NegativeArraySizeException
变量无类型,变量值才有类型,这个特点也是动态类型语言的一个重要特性。
5、字节码技术和动态代理的实现