首頁  >  文章  >  Java  >  java繼承中建立父類別物件問題詳解

java繼承中建立父類別物件問題詳解

PHP中文网
PHP中文网原創
2017-06-20 10:18:431737瀏覽

呼叫父類別建構方法是真的,但是根本沒有建立父類別對象,只不過是呼叫父類別建構方法來初始化屬性。

如果說呼叫父類別建構方法等於建立父類別對象,那就真的無稽之談。
new指令開啟空間,用來存放物件的各個屬/性參考等,反編譯字節碼你會發現只有一個new指令,所以開闢的是一塊空間,一塊空間就放一個物件。
然後,子類別呼叫父類別的屬性,方法啥的,那不是實例化的物件。
在字節碼中子類會有個u2類型的父類索引,屬於CONSTANT_Class_info類型,透過CONSTANT_Class_info的描述可以找到CONSTANT_Utf8_info,然後可以找到指定的父類啊啥的。
你的方法啊,屬性名稱都是在這個上面解析出來的,然後實際變數內容儲存在new出來的空間。 。 。
super這個關鍵字只不過是存取了這個空間特定部分的資料(也就是專門儲存父類別資料的記憶體部分)。 。 。 。 。 。

預設的hashcode和equals(直接使用的==比較)都是一樣的,所以,這根本就在一個空間裡,也不存在單獨的出來的父類物件。


如果說子類別可以強行轉換成父類別進行使用,那是因為java虛擬機器有個靜態類型(外觀類型)和實際類型的概念。
如Object t=new Point(2,3);
那麼Object就屬於靜態型別(外觀型別),Point屬於實際型別。
靜態類型和實際類型在程式中都可以發生變化,差異是靜態類型的變化僅發生在使用時發生,而變數本身的靜態類型不會改變,最終的靜態類型是在編譯期間可知的;而實際變數類型的變化結果只有在運行期間才能被確定,編譯器在編譯的時候並不知道變數的實際類型是什麼


##java物件的內存佈局是由物件所屬的類別決定。也可以這麼說,當一個類別被載入到虛擬機器中時,由這個類別所建立的物件的佈局就已經確定下來的啦。

Hotspot中java物件的記憶體佈局:

每個java物件在記憶體中都由物件頭和物件體組成。
物件頭是存放物件的元訊息,包含該物件所屬類別物件Class的參考以及hashcode和monitor的一些資訊。

物件體主要存放的是java物件本身的實例域以及從父類別繼承過來的實例域,並且內部佈局滿足由下規則:
規則1:任何物件都是8個位元組為粒度進行對齊的。
規則2:實例域依照以下優先權進行排列:長整型和雙精確度類型;整數和浮點型;字元和短整數;位元組類型和布林類型,最後是引用型別。這些實例域都依照各自的單位對齊。
規則3:不同類別繼承關係中的實例域不能混合排列。首先依照規則2處理父類別中的實例域,接著才是子類別的實例域。
規則4:當父類別中最後一個成員和子類別第一個成員的間隔如果不夠4個位元組的話,就必須擴展到4個位元組的基本單位。
規則5:如果子類別第一個實例域是一個雙精確度或長整數型,且父類別並沒有用完8個位元組,JVM會破壞規則2,依照整形(int),短整型(short),位元組型(byte),引用類型(reference)的順序,向未填滿的空間填充。
以上就是java物件的記憶體佈局的規則。

接下來說一下java物件的實例化方法,也就是常見的方法。

當我們new一個物件時,其實jvm已經把這個物件的整個空間已經分配好,整個物件的實例域佈局已經確定下來啦。
實例化方法就是將物件實例域的值設定到對應空間。

方法以呼叫父類別的方法開始,以自身建構方法結束。實例域的宣告與實例初始化語句區塊的位置關係會影響編譯器產生的方法的字節碼順序。

還是用一個例子來說明:

class Parent {
   private short six;
   private int age;
#}

class Sub extend Parent{

#    private String name;
   private int age;
   private float price;
}
目前Sub物件的記憶體佈局由下:


super所謂的父類別儲存空間的表示##目前Sub物件的記憶體佈局由下:##super所謂的父類別儲存空間的表示到底是什麼意思?
這裡的super儲存我想就是綠色的那個位置吧!

以上是java繼承中建立父類別物件問題詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn