Java的對象模型中:
- 所有的類都是Class類的實例,Object是類,那么Object也是Class類的一個實例。
- 所有的類都最終繼承自Object類,Class是類,那么Class也繼承自Object。
而第2個假設是對的:java.lang.Class是java.lang.Object的派生類,前者繼承自后者。
Java class、Object、Class 的區別?
按我的理解,
Class只是一個名字比較特殊的類,是關鍵字class修飾的類,一般應用於反射,只是名稱比較特殊而已,可以通過Class類型來獲取其他類型的元數據(metadata),比如字段,屬性,構造器,方法等等,可以獲取並調用。
class是一個關鍵字,是用來修飾類
Object是一個特殊的類,所有的類都繼承該類,包括Class也繼承Object。
類是一個語法概念,是一個抽象的概念,所有class修飾的都屬於這個概念。所有類都有一個(屬性,好像也不是屬性)class返回含有該類元數據的Class類的實例。(有點不好描述,就是比如Class a=Test.class)。
1.所有的類都是Class類的實例,Object是類,那么Object也是Class類的一個實例。
這句話是完全混亂以及不知所雲的。當然,我知道你錯在哪兒,我試着給你理一下。
中文說到“類”,對應的英文是class,ok,這是一個前提,不要認為他們是不同的東西。一個class,描述的是一個抽象的數據結構,或者說,一個class,是一個抽象數據結構的定義,記住,這里說到的class,是一個語法上的概念,並沒有實體跟它對應。
接下來,在JDK中,提供了兩個預定義的class, Object以及Class。按照Java規范,所有的class(注意我這里對class和Class的大小寫形式的區分使用,class代表的是語法概念,Class代表JDK中提供的Class數據結構)都是Object的子類,所以, Class一定是Object的子類,它用來描述所有的class的meta信息,比如它有多少個字段啊,有些什么方法啊,等等這些數據結構信息。
接下來,看實例是什么?實例是指根據抽象的class定義在運行時聲明的一段內存區間,該內存區間可以按照class的定義進行合法的訪問。所以,Object不是實例,Object是一個class,可以用一個Class的實例來描述。
最后這句話有點繞,回頭看看你的原文,“所有的類都是Class類的實例”, 類就是類,就是class,是一個語法概念,是你自己定義的一個抽象數據結構,跟實例無關,所以,自然的,Object只是一個class,而不是Class的實例。
看下面的代碼
Class cls = Object.class; Class cls = new Class(new byte[2048]); Object obj = cls.newInstance(); Object obj = new Object();
* 注意,第二行代碼實際上是不成立的,但從邏輯上比較容易理解,所以我就生造了這樣一個調用。
第一行代碼中,Class是一個class, Object也是一個class,同時,Object.class指向一個Class實例,該實例可以描述Object的數據結構(實際上,就是內存布局)。
第二行代碼,可以用來解釋,那個Object.class又是哪兒來的,實際上,就是從硬盤上讀入的class文件的二進制數據,然后通過new一個Class的實例,並傳入加載的class文件的二進制數據,Class的內部實現會解釋二進制數據並生成相應的內部描述數據。
第三行代碼,Class的newInstance方法總是通過Class的實例才能調用的,因為如上所述,我們通過實例化一個Class的手段來得到一個類的meta描述。
第四行代碼,是我們通常創建實例的手段,從邏輯上,你可以認為,第4行代碼實際上就等同於第二行代碼加上第三行。
最后,在實際的JVM實現中,並不這樣簡單,但你需要首先從邏輯上理解這些概念之間的關系,然后,自己再去深入學習。再強調一遍,我這里的描述,都只是邏輯上等價的描述,並不是實際情況。先有Class還是先有Object?
真是一個好問題!
我大概講一下我的想法,對不對不知道,只是想和大家交流一下。
應該是先有Object類再有Class類。
在實現Class類的時候,先繼承了Object類,然后編譯成.class的字節碼,這樣就能被JVM加載了。
虛擬機加載了所有類。這些類在虛擬機里都能被Class類進行描述,Object類也是,它的字段,方法什么的也都能被Class類進行描述和表示。而這個表示類的Class實例是由虛擬機裝載類時自動構造的。
so,題主明白了吧,這里面不是誰先誰后的關系,而是他們壓根不在同一個世界里。Object在Class類之前,那是在編譯期;Class能表示Object類,那是在JVM中。這個跟雞和蛋之間的關系是兩碼事,要分開在不同的場景里討論。