Java零基礎(chǔ)快速入門|this關(guān)鍵字

本篇文章主要內(nèi)容
this?是什么
this?使用在實(shí)例方法中
this?使用在構(gòu)造方法中
學(xué)習(xí)目標(biāo)
理解this 是什么,this 能用在哪里,不能用在哪里,this 什么時(shí)候可以省略,什么時(shí)候不能省略,以及怎么通過構(gòu)造方法調(diào)用當(dāng)前類中其它的構(gòu)造方法。掌握靜態(tài)代碼塊的執(zhí)行時(shí)機(jī),變量什么時(shí)候聲明為靜態(tài)變量,什么時(shí)候聲明為實(shí)例變量,方法什么時(shí)候聲明為實(shí)例方法,什么時(shí)候聲明為靜態(tài)方法,以及靜態(tài)方法中為何不能直接訪問實(shí)例變量和實(shí)例方法。
?
知識(shí)框架

?
this?是什么
this 是java 語言中的一個(gè)關(guān)鍵字,它存儲(chǔ)在內(nèi)存的什么地方呢,一起來看一段程序:


以上程序的內(nèi)存結(jié)構(gòu)圖如下所示:

this?可以看做一個(gè)變量,它是一個(gè)引用,存儲(chǔ)在Java 虛擬機(jī)堆內(nèi)存的對(duì)象內(nèi)部,this??這個(gè)引用保存了當(dāng)前對(duì)象的內(nèi)存地址指向自身,任何一個(gè)堆內(nèi)存的 java 對(duì)象都有一個(gè)this,也就是說創(chuàng)建100 個(gè)java 對(duì)象則分別對(duì)應(yīng)100 個(gè)this。通過以上的內(nèi)存圖,可以看出“jack 引用”保存的內(nèi)存地址是0x1111,對(duì)應(yīng)的“this 引用”保存的內(nèi)存地址也是 0x1111,所以“jack 引用” 和“this 引用”是可以劃等號(hào)的。也就是說訪問對(duì)象的時(shí)候jack.name 和this.name 是一樣的, 都是訪問該引用所指向?qū)ο蟮?/span>name 屬性。
this 指向“當(dāng)前對(duì)象”,也可以說 this?代表“當(dāng)前對(duì)象”,this 可以使用在實(shí)例方法中以及構(gòu)造方法中,語法格式分別為“this.”和“this(..)”。this 不能出現(xiàn)在帶有static 的方法當(dāng)中。
?
this 使用在實(shí)例方法中
我們來看看this 是否可以出現(xiàn)在static 的方法當(dāng)中,請(qǐng)看以下代碼以及編譯結(jié)果:

編譯報(bào)錯(cuò),如下圖所示:

通過以上的測(cè)試得知this 不能出現(xiàn)在static 的方法當(dāng)中,這是為什么呢?首先static?的方法, 在調(diào)用的時(shí)候是不需要?jiǎng)?chuàng)建對(duì)象的,直接采用“類名”的方式調(diào)用,也就是說static??方法執(zhí)行的過程中是不需要“當(dāng)前對(duì)象”參與的,所以static?的方法中不能使用this,因?yàn)?this 代表的就是“當(dāng)前對(duì)象”。
大家是否還記得在之前的“封裝”過程中,曾編寫屬性相關(guān)的 set 和 get 方法,set 和 get 方法在聲明的時(shí)候不允許帶static?關(guān)鍵字,我們把這樣的方法叫做實(shí)例方法,說到實(shí)例方法,大家肯定想到了實(shí)例變量,沒錯(cuò),實(shí)例變量和實(shí)例方法都是對(duì)象相關(guān),必須有對(duì)象的存在,然后通過“引用”去訪問。
為什么set?和?get?方法設(shè)計(jì)為實(shí)例方法呢?那是因?yàn)?/span>set?和get?方法操作的是實(shí)例變量,“不同的對(duì)象”調(diào)用 get 方法最終得到的數(shù)據(jù)是不同的,例如 zhangsan 調(diào)用 getName()方法得到的名字是 zhangsan,lisi?調(diào)用 getName()方法得到的名字是 lisi,顯然 get 方法是一個(gè)對(duì)象級(jí)別的方法,不能直接采用“類名”調(diào)用,必須先創(chuàng)建對(duì)象,再通過“引用”去訪問。
this?可以出現(xiàn)在實(shí)例方法當(dāng)中,因?yàn)閷?shí)例方法在執(zhí)行的時(shí)候一定是對(duì)象去觸發(fā)的,實(shí)例方法一定是對(duì)象才能去調(diào)用的,而this?恰巧又代表“當(dāng)前對(duì)象”,所以“誰”去調(diào)用這個(gè)實(shí)例方法this?就是“誰”。測(cè)試一下,請(qǐng)看以下代碼:


運(yùn)行結(jié)果如下圖所示:

以上代碼的輸出結(jié)果具體是什么不重要,重要的是可以看出誰和誰是相等的。運(yùn)行結(jié)果和代碼結(jié)合起來分析一下this:
?

通過以上內(nèi)容的學(xué)習(xí)得知,this 可以使用在實(shí)例方法當(dāng)中,它指向當(dāng)前正在執(zhí)行這個(gè)動(dòng)作的對(duì)象。
大家是否還記得實(shí)例變量怎么訪問?正規(guī)的訪問方式是采用“引用.”去訪問。請(qǐng)看下面的代碼:


運(yùn)行結(jié)果如下圖所示:

將以上部分代碼片段取出來進(jìn)行分析:


把完整的代碼拿過來:


運(yùn)行結(jié)果如下圖所示:

通 過以上 的測(cè)試 我們得 知: System.out.println(name?+ " is shopping!") 和System.out.println(this.name?+ " is?shopping!")是等效的。也就是說在 shopping()這個(gè)“實(shí)例方法”當(dāng)中直接訪問“實(shí)例變量”name?就表示訪問當(dāng)前對(duì)象的 name。
換句話說在實(shí)例方法中可以直接訪問當(dāng)前對(duì)象的實(shí)例變量,而“this.”是可以省略的?!皌his.”什么時(shí)候不能省略呢?請(qǐng)看以 下代碼:

你有沒有看到 name=_name?這樣的代碼很丑陋,怎樣可以優(yōu)雅一些呢?請(qǐng)看:

以上代碼當(dāng)中 this.name?= name,其中 this.name?表示實(shí)例變量 name,等號(hào)右邊的 name?是局部變量 name,此時(shí)如果省略“this.”,則變成 name?= name,這兩個(gè) name?都是局部變量(java?遵守就近原則),和實(shí)例變量 name?無關(guān)了,顯然是不可以省略“this.”的。
最終的結(jié)論是,this 不能出現(xiàn)在 static 的方法中,可以出現(xiàn)在實(shí)例方法中,代表當(dāng)前對(duì)象,大部分情況下 this?都是可以省略的,只有當(dāng)在實(shí)例方法中區(qū)分局部變量和實(shí)例變量的時(shí)候不能省略。
接下來我們?cè)賮頂U(kuò)展一下 this?的使用,請(qǐng)看代碼:


運(yùn)行結(jié)果如下圖所示:

通過以上的測(cè)試,可以看出在一個(gè)實(shí)例方法當(dāng)中可以直接去訪問其它的實(shí)例方法,方法是對(duì)象的一種行為描述,實(shí)例方法中直接調(diào)用其它的實(shí)例方法,就表示“當(dāng)前對(duì)象”完成了一系列行為動(dòng)作。例如在實(shí)例方法shopping()中調(diào)用另一個(gè)實(shí)例方法pay(),這個(gè)過程就表示jack?在選購商品,選好商品之后,完成支付環(huán)節(jié),其中選購商品是一個(gè)動(dòng)作,完成支付是另一個(gè)動(dòng)作。接下來繼續(xù)擴(kuò)展,請(qǐng)看以下代碼:

以上代碼編譯報(bào)錯(cuò)了,請(qǐng)看:

為什么會(huì)編譯報(bào)錯(cuò),在 main?方法中為什么無法直接訪問變量 i?我們來分析一下,首先i 變量是實(shí)例變量,實(shí)例變量要想訪問必須先創(chuàng)建對(duì)象,然后通過“引用”去訪問,main 方法是static?的方法,也就是說 main 方法是通過“類名”去調(diào)用的,在 main 方法中沒有“當(dāng)前對(duì)象”的概念,也就是說 main 方法中不能使用this,所以編譯報(bào)錯(cuò)了。那應(yīng)該怎么修改呢?請(qǐng)看:

運(yùn)行結(jié)果如下圖所示:

通過以上的測(cè)試得知,在 static 的方法中不能直接訪問實(shí)例變量,要訪問實(shí)例變量必須先自己創(chuàng)建一個(gè)對(duì)象,通過“引用”可以去訪問,不能通過 this ?訪問,因?yàn)樵?static 方法中是不能存在 this 的。其實(shí)這種設(shè)計(jì)也是有道理的,因?yàn)?static 的方法在執(zhí)行的時(shí)候是采用“類名”去調(diào)用,沒有對(duì)象的參與,自然也不會(huì)存在當(dāng)前對(duì)象,所以 static?的方法執(zhí)行過程中不存在this。
那么在static 方法中能夠直接訪問實(shí)例方法嗎?請(qǐng)看以下代碼:

編譯報(bào)錯(cuò)了,請(qǐng)看下圖:

為什么在 main 方法中無法直接調(diào)用實(shí)例方法 doSome()呢?很簡(jiǎn)單,因?yàn)閷?shí)例方法必須先創(chuàng)建對(duì)象,通過引用去調(diào)用,在以上的main?方法中并沒有創(chuàng)建對(duì)象,更沒有this。所以在main 方法中無法直接訪問實(shí)例方法。結(jié)論就是:在 static 的方法中不能直接訪問實(shí)例方法。怎么修改呢?同樣需要先創(chuàng)建對(duì)象,請(qǐng)看:

運(yùn)行結(jié)果如下圖所示:

綜上所述,我們需要記住這樣的一個(gè)結(jié)論:this?不能使用在static 的方法中,可以使用在實(shí)例方法中,代表當(dāng)前對(duì)象,多數(shù)情況下this 是可以省略不寫的,但是在區(qū)分局部變量和實(shí)例變量的時(shí)候不能省略,在實(shí)例方法中可以直接訪問當(dāng)前對(duì)象實(shí)例變量以及實(shí)例方法,在static 方法中無法直接訪問實(shí)例變量和實(shí)例方法。
this使用在構(gòu)造方法中
this?還有另外一種用法,使用在構(gòu)造方法第一行(只能出現(xiàn)在第一行,這是規(guī)定,記住就行),通過當(dāng)前構(gòu)造方法調(diào)用本類當(dāng)中其它的構(gòu)造方法,其目的是為了代碼復(fù)用。調(diào)用時(shí)的語法格式是:this(實(shí)際參數(shù)列表),請(qǐng)看以下代碼:



運(yùn)行結(jié)果如下圖所示:

我們來看看以上程序的無參數(shù)構(gòu)造方法和有參數(shù)構(gòu)造方法:

通過上圖可以看到無參數(shù)構(gòu)造方法中的代碼和有參數(shù)構(gòu)造方法中的代碼是一樣的,按照以上方式編寫,代碼沒有得到重復(fù)使用,這個(gè)時(shí)候就可以在無參數(shù)構(gòu)造方法中使用“this(實(shí)際參數(shù)列表);”來調(diào)用有參數(shù)的構(gòu)造方法,這樣就可以讓代碼得到復(fù)用了,請(qǐng)看:


還是使用以上的main?方法進(jìn)行測(cè)試,運(yùn)行結(jié)果如下:

在this()上一行嘗試添加代碼,請(qǐng)看代碼以及編譯結(jié)果:



通過以上測(cè)試得出:this()語法只能出現(xiàn)在構(gòu)造方法第一行,這個(gè)大家記住就行了。
最后附Java零基礎(chǔ)視頻教程給大家,配合學(xué)習(xí)效果更佳?。?/strong>


?
?