您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Java類是怎么默認(rèn)繼承Object的”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Java類是怎么默認(rèn)繼承Object的”吧!
學(xué)過Java
的人都知道,Object
是所有類的父類。但是你有沒有這樣的疑問,我并沒有寫extends Object
,它是怎么默認(rèn)繼承Object的呢?
那么今天我們就來看看像Java這種依賴于虛擬機(jī)的編程語言是怎樣實(shí)現(xiàn)默認(rèn)繼承Object的,以及Java編譯器
和JVM
到底是如何做的?
首先我們來驗(yàn)證一下Object是不是所有類的父類,隨便新建一個(gè)Java類,如下圖:
從上面的代碼可以看出,new MyClass()打點(diǎn)之后可以選擇調(diào)用的方法有很多,我們定義的MyClass類里面只有一個(gè)main方法,那這些方法哪來的,顯然是Object里聲明的,故MyClass類的父類就是Object,因此,在MyClass中可以使用Object類的public或protected資源。
另外,當(dāng)A類繼承MyClass類時(shí),通過打點(diǎn)也可以調(diào)到Object內(nèi)的方法,這是繼承的傳遞,好比Object是MyClass的“父親”,MyClass是A類的“父親”,Object是A類的“爺爺”,間接的繼承了Object。
因此,Object是超類,是所有類的父類。
要了解Java類是如何默認(rèn)繼承Object的?
的原因其實(shí)并不需要知道JVM的實(shí)現(xiàn)細(xì)節(jié)。只需了解一下對于這種虛擬機(jī)程序的基本原理即可。一般對于這種靠虛擬機(jī)運(yùn)行的語言(如Java、C#等)會有兩種方法處理默認(rèn)繼承問題。
在編譯源代碼時(shí),當(dāng)一個(gè)類沒有顯式標(biāo)明繼承的父類時(shí),編譯器會為其指定一個(gè)默認(rèn)的父類(一般為Object),而交給虛擬機(jī)處理這個(gè)類時(shí),由于這個(gè)類已經(jīng)有一個(gè)默認(rèn)的父類了,因此,VM仍然會按照常規(guī)的方法像處理其他類一樣來處理這個(gè)類。對于這種情況,從編譯后的二進(jìn)制角度來看,所有的類都會有一個(gè)父類(后面可以以此依據(jù)來驗(yàn)證)。
編譯器仍然按照實(shí)際代碼進(jìn)行編譯,并不會做額外的處理,即如果一個(gè)類沒有顯式地繼承于其他類時(shí),編譯后的代碼仍然沒有父類。然后由虛擬機(jī)運(yùn)行二進(jìn)制代碼時(shí),當(dāng)遇到?jīng)]有父類的類時(shí),就會自動將這個(gè)類看成是Object類的子類(一般這類語言的默認(rèn)父類都是Object)。
從上面兩種情況可以看出,第1種情況是在編譯器上做的文章,也就是說,當(dāng)沒有父類時(shí),由編譯器在編譯時(shí)自動為其指定一個(gè)父類。第2種情況是在虛擬機(jī)上做文章,也就是這個(gè)默認(rèn)的父類是由虛擬機(jī)來添加的。
那么Java是屬于哪一種情況呢?其實(shí)這個(gè)答案很好得出。只需要隨便找一個(gè)反編譯工具,將.class文件進(jìn)行反編譯即可得知編譯器是如何編譯的。
就以上面代碼為例,如果是第1種情況,就算MyClass沒有父類,但由于編譯器已經(jīng)為MyClass自動添加了一個(gè)Object父類,所以,在反編譯后得到的源代碼中的MyClass類將會繼承Object類的。如果不是這種情況,那么就是第2種情況。
那么實(shí)際情況是什么樣的呢?現(xiàn)在我們就將MyClass.class反編譯看看到底如何。
jd-gui反編:
使用JDK自帶的工具(javap)反編譯
CMD命令行下執(zhí)行:
javap MyClass>MyClass.txt
可以看出實(shí)際的反編譯后的文件中并沒有extends Object
,使用排除法,因此是第2情況。
這樣來推導(dǎo)出的結(jié)論是第2種情況,但事實(shí)真的如此嗎?為什么網(wǎng)上還有說反編譯后的是有extends Object
字樣?
JDK版本問題?
猜想是JDK版本的問題,于是把JDK版本切換到7,使用jd-gui和javap反編譯,接果和使用JDK8反編譯后的結(jié)果一樣,也都沒有extends Object
。
繼續(xù)換版本,昨晚在宿舍準(zhǔn)備到Oracle官網(wǎng)下載JDK 6,但是死活下不來,今早到公司后第一件事就是下載,很順利,安裝后把JDK版本切換到JDK 6。
仍然在CMD窗口執(zhí)行javap MyClass>MyClass.txt
,得到的TXT文件內(nèi)容如下:
what?竟然有extends Object
,jd-gui反編譯后的依然沒有。 即,JDK 6之前使用javap反編譯后的MyClass類顯式的繼承Object,JDK 7以后沒有;jd-gui反編譯后的不管JDK版本如何始終沒有。我們以java自帶的工具為準(zhǔn)。
那么就是說JDK 6之前是編譯器
處理,JDK 7之后是虛擬機(jī)
處理。
但是仔細(xì)想想我們在編輯器
里(IDE)打點(diǎn)時(shí)就能列出Object類下的方法,此時(shí)還沒輪到編譯器和jvm,編輯器就已經(jīng)知道MyClass類的父類是Object類了,這是因?yàn)榫庉嬈鳛槲覀冏隽艘恍┲悄芴幚怼?/p>
到此,相信大家對“Java類是怎么默認(rèn)繼承Object的”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。