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

浙公網(wǎng)安備 33010602011771號