1. 程式人生 > 其它 >深入探究Java中的物件型別變數宣告操作——在宣告物件時,系統究竟做了什麼?

深入探究Java中的物件型別變數宣告操作——在宣告物件時,系統究竟做了什麼?

深入探究Java中的物件型別變數宣告操作——在宣告物件時,系統究竟做了什麼?

摘要:本文主要對Java中的物件型別變數的宣告的底層原理做了探究。

@

目錄
​ 我們但凡是學過Java的,一定都知道Java中的物件型別變數的宣告方式,那就是:類名 變數名 = new 類名()。不管這樣說對不對,我們在這樣寫的時候,一定都是這樣寫的。比如我們寫了一個Person類,在宣告變數的時候,就要這樣寫:
Person liMing = new Person();

​ 我們並不會深入的去思考為什麼這麼寫,這個語句中的主角是什麼,這些問題我們都沒有仔細去想過,因此在這裡,我詳細探討這個問題,解決你心中的疑惑。

1.控制代碼

​ 在之前的學習中,我們實際上已經探究了控制代碼的原理,在這裡我們再鞏固一下。控制代碼就是我們常說的變數的變數名,一個變數是由變數名和值構成的,對於我們來說,變數的名字就是變數名,對於計算機來說,變數的變數名部分被稱為控制代碼。我們在宣告變數之後,變數就會在被宣告的位置儲存起來,如類的屬性變數,就會被儲存到位於堆記憶體中的物件例項中去,而方法中的變數,會在方法被呼叫的時候,執行到變數宣告的地方在相應的棧空間上建立,變數被建立之後,虛擬機器就可以根據控制代碼進行值的尋找了,當我們在變數建立之後呼叫變數,虛擬機器就可以根據變數名來尋找控制代碼,並找到控制代碼後邊的值進行取值,進而進行運算,正因如此,Java中的控制代碼和值是相鄰的,而相對應的,在進行一個變數宣告賦值的時候,等號左邊的變數名就是控制代碼,右邊的則是值。

​ 對於這個概念,我們在使用基本型別變數時非常好理解,對於基本型別變數的宣告方式我們也很容易理解了,如下:

int a = 10;

​ 首先是宣告型別為整形,控制代碼為a,這就引起了一個操作:先在棧空間上開闢了一個空間存放控制代碼,然後控制代碼的後邊就是一塊連續的32位大小的空間,這個空間就是變數a的值空間。而等號操作就會導致等號右邊的值:10被放到值空間中。這樣一個基本型別變數就宣告好了,那麼一個物件型別的變數是如何宣告的呢?

2.物件型別變數的宣告

​ 在物件型別變數的宣告中,主角實際上是new,new關鍵字是這之中最為關鍵的東西。new是一個關鍵詞,但是它實際上代表著一系列操作的執行,它屬於一個操作開關,虛擬機器一旦檢測到new,就會執行一系列的操作。

Person liMing = new Person();

​ 在這個宣告賦值之中,最前邊的Person實際上是變數型別宣告,它在整個操作的過程中,起到的作用是型別宣告,但它實際上是new總體操作的一個引數,new會根據這個型別宣告,使用路徑定位的方式,尋找這個類,想要能建立這個型別的變數,就得讓new能通過Person這個字串,順著路徑能夠找到它的類資訊,我們如何讓new通過路徑找到它呢?實際上我們在Java中書寫的import匯入路徑,就是在幫助new定址,new的定址能力並不特別行,它只能在當前程式所在的包下直接尋找,如果要是想尋找更多的東西,就要為程式加地址索引,也就是最上邊的import,new會遍歷它們並按照它們的路徑尋找。

​ 當new尋找到相應的類資訊後,就會檢測這個類是否被初始化過,簡而言之,就是檢查這個類是否生成過物件,如果沒有,就會對它進行forname()方法,這個方法是反射中的方法,使用這個方法可以獲取這個類的所有資訊,擁有類的所有資訊之後,就可以通過它們來生成例項了。

​ 在初始化或者類被初始化過之後,就可以拿到類資訊在堆空間中建立這個類的例項了,new會建立好這個例項,至此,物件實體的建立就完成了,然而對我們程式設計師來說,它沒有真正的完成,因為它只是存在了,我們還沒拿到它,因此new操作在最後會返回一個地址,這個地址通過等號的賦值功能被放在liMing控制代碼的後邊,然而事情沒那麼簡單,它還有一個操作。new的最後一個引數,便是神奇的構造器,在new後邊書寫,構造器會在new的所有操作完成前執行,構造器的作用並不是構造,構造是new的操作,我們更喜歡將構造器稱之為init()方法,即初始化方法,在Java中也有類似的方法。構造器乾的事情是在new返回地址之前對物件進行一些初始化操作,具體怎麼初始化其實是我們自己定的,我們會在構造器中寫自己想要進行的操作,比如給哪個屬性賦值什麼的,構造器就會在返回地址之前進行這些操作,在構造器完成之後,地址被返回給控制代碼,至此,我們就可以使用這個變量了。

3.重點

​ 構造器並不是構造物件的,new才是,構造器只是在初始化物件,最重要的操作是new關鍵字引起的操作,new實際上是一種簡寫機制,使用了封裝思想,就是使用new關鍵字來代表一系列的操作執行,這個操作由虛擬機器執行,我們只要寫一個簡單的new就行了,這是一種人性化的設計方式,最前邊的類名是型別宣告,也是一個引數,new中的操作會拿著這個引數進行類資訊的尋找,如果找不到就會報錯,在new內部還涉及了部分反射的知識,關於這裡的研究我認為非常重要,以後還需繼續深入學習。

​ 本文參考了兩篇不錯的博文,在此給出連結:

Java中new一個物件是一個怎樣的過程?JVM中發生了什麼? - 額是無名小卒兒 - 部落格園 (cnblogs.com)

Java new關鍵字的物件記憶體分配原理 - naray - 部落格園 (cnblogs.com)