1.动态连接(链接)
java代码在进行javac编译的时候不会像c或者c++有“连接”这一步骤,而是虚拟机在加载Class文件的时候进行动态连接。也就是说在class文件中不会保存各个方法,字段最终在内存中的入口地址,也就无法被虚拟机直接使用。(摘自深入理解java虚拟机)
通俗的说就是就java在完成编译的时候方法字段在连接前不会分配内存。
2.运行期类加载机制
java虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成被虚拟机直接使用的java类型的过程叫做类加载机制。与c++这种在编译时需要进行连接的语言不同。这种策略给java带来了极高的扩展性。比如用户可以通过java预置的自定义类加载器,让某个本地的应用程序在运行时加载一个二进制流成为程序代码的一部分。
3.运行期异常与编译期报错
int main(void){
int i[1][0][-1]; // gcc拒绝编译 size of array is negative
return 0;
}
public void main (String[] args){
int[][][] array = new int[1][0][-1];
}
报运行时异常(NegativeArraySizeException)
4.动态绑定(多态)
在运行时期根据具体对象的类型进行绑定。编译器在运行时此时依然不知道对象的类型,但方法调用机制能自己去调查,找到正确的方法主体。
1.虚拟机提取对象实际类型的方法表
2.虚拟机搜索方法签名
3.调用方法
多态简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”,
5 .虚方法
5.1 非虚方法: (static)静态方法,(private)私有方法,实例构造器父类方法,final方法。
虚方法:java中的虚方法表存放着各个方法的实际入口地址,将在类加载的连接阶段进行初始化。
5.2 c++虚函数 虚函数源于c++中的类继承,是多态的一种。在c++中,一个基类的指针或者引用可以指向或者引用派生类的对象。同时,派生类可以重写基类中的成员函数。多态用虚函数来实现,结合动态绑定。
6.总结
- 动态连接主要和c/c++这种在编译期间就分配了内存的对比。java是在运行时候才分配;
- 有静态绑定和动态绑定;重载是静态绑定;多态是动态绑定;父类的指针通过虚方法表来找到子类对应方法
- C++中 当函数被virtual关键字修饰时,该函数被称为虚函数