http://blog.csdn.net/linxdcn/article/details/72850375
本人基于上文做了简单的整理,解释及拓展,方便像和我一样不熟悉C++的人能更好的理解原文中的一些概念
介绍
HotSpot是基于c++实现,而c++是一门面向对象的语言,本身具备面向对象基本特征,所以Java中的对象表示,最简单的做法是为每个Java类生成一个c++类与之对应。
但HotSpot JVM并没有这么做,而是设计了一个OOP-Klass Model。这里的 OOP 指的是 Ordinary Object Pointer (普通对象指针),它用来表示对象的实例信息,看起来像个指针实际上是藏在指针里的对象。而 Klass 则包含元数据和方法信息,用来描述Java类。
之所以采用这个模型是因为HotSopt JVM的设计者不想让每个对象中都含有一个vtable(虚函数表),所以就把对象模型拆成klass和oop,其中oop中不含有任何虚函数,而Klass就含有虚函数表,可以进行method dispatch。
OOP-Klass 模型是对象在JVM中的表示
Klass
Klass
: 包含元数据和方法信息,用来描述Java类
Klass主要有两个功能:
- 实现语言层面的Java类
- 实现Java对象的分发功能
一般jvm在加载class文件时,会在方法区创建instanceKlass,表示其元数据,包括常量池、字段、方法等。
OOP
OOP
: Ordinary Object Pointer (普通对象指针),它用来表示对象的实例信息,看起来像个指针实际上是藏在指针里的对象
Klass是在class文件在加载过程中创建的,OOP则是在Java程序运行过程中new对象时创建的。
一个OOP对象包含以下几个部分:
- instanceOopDesc,也叫对象头
- Mark Word,主要存储对象运行时记录信息,如hashcode, GC分代年龄,锁状态标志,线程ID,时间戳等
- 元数据指针,即指向方法区的instanceKlass实例
- 实例数据
目的
HotSopt JVM的设计者不想让每个对象中都含有一个vtable(虚函数表),所以就把对象模型拆成klass和oop,其中oop中不含有任何虚函数,而Klass就含有虚函数表,可以进行method dispatch。
关键词解析
vtable
: C++中每一个有虚函数的类,都有vtable(虚函数表)
虚函数
: 同Java方法(函数),C++中的有虚函数的概念,用virtual 关键字来表示,每个类都会有一个虚函数表,该虚函数表首先会从父类中继承得到父类的虚函数表, 如果子类中重写了父类的虚函数(不管重写后的函数是否为虚函数),要调用哪个虚函数,是根据当前实际的对象来判断的(不管指针所属类型是否为当前类,有可能是父类型),指针当前指向的是哪种类型的对象,就调用哪个类型中类定义的虚函数。每个类只有一张虚拟函数表,所有的对象共用这张表。在Java中,自动实现了虚函数这一概念:多态——父类的变量,调用子类的方法
纯虚函数
: 同Java抽象方法,C++中主要特征是不能被用来声明对象,是抽象类,是用来确保程序结构与应用域的结构据具有直接映射关系的设计工具。带有纯虚函数的类称为抽象类,抽象类能被子类 继承使用,在子类中必须给出纯虚函数的实现,如果子类未给出该纯虚函数的实现,那么该子类也是抽象类,只有在子类不存在纯虚函数时,子类才可以用来声明对 象!抽象类也能用于声明指针或引用,或用于函数声明中。具有抽象类特性的类还有构造函数和析构函数,全部是保护的类。如果没有给出纯虚函数的实现,则在它 所在的类的构造函数或析构函数中不能直接或间接的调用它。纯虚函数的实现可以在类声明外进行定义。
抽象类
: 同Java抽象类,C++中指同时含有纯虚函数和非纯虚函数的类
纯虚类
: 同Java接口,C++中指只含有纯虚函数的类
C++ | Java |
---|---|
虚函数 | 普通函数 |
纯虚函数 | 抽象函数 |
抽象类 | 抽象类 |
纯虚类 | 接口 |
拓展: C++中普通函数不存在多态——不会根据实际的对象来判断调用函数,而是直接调用当前变量类型的方法
实例说明
class Model
{
public static int a = 1;
public int b;
public Model(int b) {
this.b = b;
}
}
public static void main(String[] args) {
int c = 10;
Model modelA = new Model(2);
Model modelB = new Model(3);
}
上述代码得OOP-Klass模型入下所示