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模型入下所示