java中this图解_JAVA-初步认识-第七章-this关键字的使用场景和原理图解
一.
this有什么用?我們用例子的形式來體現一下。
下面的截圖說明,給人對象一初始化的時候,賦值個姓名。賦值姓名的時候,拿n賦值給name,
DOS顯示創建對象時,構造函數初始化成功。
在例子中,我們將“旺財”提供給了n,但是在描述類中,我們要先確定是哪個構造函數中的n。我們看到描述類中,有Person(String n)這個構造函數,至于構造函數里面是怎么寫的,我們不知道,對我們而言,里面是封裝的。光看函數聲明,n到底是什么意思,我們不可能從變量名稱上獲取n所接受的數據的信息。我們希望提高一下代碼的閱讀性,寫n看不懂,寫一個閱讀性強一點的,一目了然(那這里的形參可以是字符串么?)。
直接將構造函數中的形參n,改成字符串name,可以很清楚的知道,我們輸入的數據是什么。執行以下源程序,編譯沒問題,但是運行時出錯了,不是我們設想的結果。
解析:分析的同時,回顧一下,各部分在內存中的分布機理。創建的對象位于堆內存中,依據描述事物的類,將成員變量加載入堆內存中的對象空間里,分配地址編號,對成員變量進行默認初始化。在初始化結束前,還要調用構造函數。調用的構造函數是加載入棧內存中,同時將構造函數中的形參name載入棧的構造函數空間內(此時的形參name,會不會有一個默認初始化的值?),由于對象創建時調用了構造函數,給定了輸入數據,那么name就有確定數據“旺財”。接著繼續執行構造函數里面的語句,里面是將name的值賦值給name。→這里又理解岔了。將構造函數的形參載入棧中的構造函數時,就直接執行構造函數里的語句了,而并不是急于和對象產生關系。形參name載入時,里面的執行語句是將name值賦值給name值,在棧的構造函數里,目前name已經存在了,就不需要向外界搜索name了。這里面name的null值是怎么來的,我覺得是在定義構造函數時,輸入形參,就相當于在定義一個name變量,而且沒有賦值,那么系統就自動給一個默認的值null。這時構造函數中的name在對自己進行賦值,那么name的值還是默認的null值。對象中的成員變量name并沒有改變,這就是局部變量和成員變量重名。→這里,還是理解的不對。堆中對象里的成員變量在,對象分配地址編號后就直接默認初始化了。構造函數是隨著創建對象時,成員變量默認初始化后反生的。在這里,我就認為,對象的構造函數初始化發生后,對象的創建才完成。輸入的“旺財”到底哪去了?在創建對象時,我們知道對象是調用構造函數進行了初始化。這里的調用就是將 確定的輸入數據“旺財”給了構造函數,也就是說,從形參name一加載進棧中的person構造函數空間后,那么name的值就是被賦予了“旺財”。這時,繼續執行構造函數里面的內容,name=name,由于構造函數里就有name,自己給自己賦值,相當于沒變化。這時,重點來了,棧中的局部變量name和堆中的成員變量name是沒有任何關系的,僅僅只是名字相同,而且隨著構造函數的執行完畢(構造函數執行結束后,直接彈棧,“旺財”的輸入對對象一點意義都沒有),系統就認為對象創建結束了。這時再進行p.speak()時,一般函數speak的功能是輸出對象中的成員變量name和age,由于對象中兩個成員變量的值始終是默認初始化的值,所以仍然是null和0。
局部變量和成員變量重名,導致構造函數和對象之間無法形成指向?,F在我們必須想辦法,將兩者聯系起來。這時,就需要關鍵字this。this.name就是這個對象的name,將構造函數的值為“旺財”的name賦值給對象的name,將兩個name做了區分。
上面這一切發生的緣由是什么,為了提高構造函數的可讀性,將形參名和成員變量名統一,提高可讀性。但這樣導致構造函數無法對對象進行初始化,這時就引入了this關鍵字,區分成員變量和局部變量。
this就是引用,引用對象。在創建對象調用的構造函數入棧后,為了明確兩者之間的對應關系,在明確的輸入值賦值給形參name之前,
需要給構造函數中,加入一個this。構造函數中的this指向哪個對象,它就給哪個對象初始化,至于是否真的對對象進行了初始化,并不確定,只是起一個對應指向的作用。其實person被對象調用,進內存時,對象就給了一個this值。通過this關鍵字,對象標定了構造函數。而且this有明確的值0x0045,不是那種系統默認的一個初始化值。
將person()類中的語句,完整地書寫出來,語句如下。
執行完person中語句后,將person方法彈棧,在彈棧前,已經根據this.name="旺財",給堆中對象的成員變量name賦值了。
在person方法彈棧結束后,表明對象已經創建完畢。這時,再將對象的地址編號賦值給局部變量p。
緊接著程序為p.speak()。它是用來說出某個對象的姓名和年齡。因此,speak方法在進內存前,也有一個所屬關鍵字this。speak方法的功能是輸出name和age,但是棧中的speak方法中,沒有定義過name和age局部變量,所以speak訪問的全是成員變量,speak能明確哪個對象里的成員變量么?必須要加上this.。
?
目前談論的添加關鍵字this的緣由就是,構造函數中的形參和成員變量重名,以及一個this的指引作用。
這時接著執行下面的程序,也就是除了p外,還有p1。
隨著p1變量對應的對象新建,person又開始進棧。這里我們在捋一遍這個過程。棧中載在局部變量p1,堆中創建對象。對象的創建是依據描述類中的內容來的,在對象分配完地址編號后,立即在對象中載入成員變量name,age,同時對它們進行默認初始化。在創建對象時,還要接著用構造函數進行初始化。由于創建對象時,輸入的數據是“小強”,這對應著person(String name)的構造函數。這樣就調用了person(String name)構造函數,為了明確是p1調用的,給了person方法一個this=0x0089的編號,意思是,是0089調用的構造函數。在調用時,將確定的數據“小強”賦值給了person方法中的name局部變量,這時為了使構造函數對對象中的成員進行初始化(局部變量和成員是一樣的名字,為了建立聯系,必須給出指向),語句書寫為this.name=name,也就是說將局部變量name的值“小強”賦值給this為089的name,最后再來一個return,彈棧。這時也標志著0089的對象創建完畢。
最初,person中的局部變量和對象中的成員變量不重名的時候,this不寫也是可以的。
但是為了嚴謹性,也是為了提高可讀性,最終程序的書寫都標注了this。
總結
以上是生活随笔為你收集整理的java中this图解_JAVA-初步认识-第七章-this关键字的使用场景和原理图解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蛋糕是叫胚子还是坯子_教你做巧克力淋面蛋
- 下一篇: 离群点检测方法_干货 :时间序列异常检测