本篇內(nèi)容主要講解“使用This完成的工作有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“使用This完成的工作有哪些”吧!
成都創(chuàng)新互聯(lián)是一家專注于成都網(wǎng)站建設(shè)、網(wǎng)站制作與策劃設(shè)計(jì),萬州網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:萬州等地區(qū)。萬州做網(wǎng)站價(jià)格咨詢:028-86922220
01、 指向當(dāng)前對(duì)象
“三妹,來看下面這段代碼?!痹捯魟偮?,我就在鍵盤上噼里啪啦一陣敲。
public class WithoutThisStudent { String name; int age; WithoutThisStudent(String name, int age) { name = name; age = age; } void out() { System.out.println(name+" " + age); } public static void main(String[] args) { WithoutThisStudent s1 = new WithoutThisStudent("沉默王二", 18); WithoutThisStudent s2 = new WithoutThisStudent("沉默王三", 16); s1.out(); s2.out(); } }
“在上面的例子中,構(gòu)造方法的參數(shù)名和實(shí)例變量名相同,由于沒有使用 this 關(guān)鍵字,所以無法為實(shí)例變量賦值。”我抬起右手的食指,指著屏幕上的 name 和 age 對(duì)著三妹說。
“來看一下程序的輸出結(jié)果?!?/p>
null 0 null 0
“從結(jié)果中可以看得出來,盡管創(chuàng)建對(duì)象的時(shí)候傳遞了參數(shù),但實(shí)例變量并沒有賦值。這是因?yàn)槿绻麡?gòu)造方法中沒有使用 this 關(guān)鍵字的話,name 和 age 指向的并不是實(shí)例變量而是參數(shù)本身?!蔽野巡弊优は蛴覀?cè),看著三妹說。
“那怎么解決這個(gè)問題呢?哥?!比弥钡貑枴?/p>
“如果參數(shù)名和實(shí)例變量名產(chǎn)生了沖突.....”我正準(zhǔn)備給出答案,三妹打斷了我。
“難道用 this 嗎?”三妹脫口而出。
“哇,越來越棒了呀,你?!蔽腋杏X三妹在學(xué)習(xí) Java 這條道路上逐漸有了自己主動(dòng)思考的意愿。
“是的,來看加上 this 關(guān)鍵字后的代碼?!?/p>
安靜的屋子里又響起了一陣噼里啪啦的鍵盤聲。
public class WithThisStudent { String name; int age; WithThisStudent(String name, int age) { this.name = name; this.age = age; } void out() { System.out.println(name+" " + age); } public static void main(String[] args) { WithThisStudent s1 = new WithThisStudent("沉默王二", 18); WithThisStudent s2 = new WithThisStudent("沉默王三", 16); s1.out(); s2.out(); } }
“再來看一下程序的輸出結(jié)果?!?/p>
沉默王二 18 沉默王三 16
“這次,實(shí)例變量有值了,在構(gòu)造方法中,this.xxx 指向的就是實(shí)例變量,而不再是參數(shù)本身了?!蔽衣掏痰卣f著,“當(dāng)然了,如果參數(shù)名和實(shí)例變量名不同的話,就不必使用 this 關(guān)鍵字,但我建議使用 this 關(guān)鍵字,這樣的代碼更有意義?!?/p>
03、調(diào)用當(dāng)前類的方法
“仔細(xì)聽,三妹,看我敲鍵盤的速度是不是夠快。”
public class InvokeCurrentClassMethod { void method1() {} void method2() { method1(); } public static void main(String[] args) { new InvokeCurrentClassMethod().method1(); } }
“仔細(xì)瞧,三妹,上面這段代碼中沒有見到 this 關(guān)鍵字吧?”我面帶著神秘的微笑,準(zhǔn)備給三妹變個(gè)魔術(shù)。
“確實(shí)沒有,哥,我確認(rèn)過了?!?/p>
“那接下來,神奇的事情就要發(fā)生了。”我突然感覺劉謙附身了。
我快速的在 classes 目錄下找到 InvokeCurrentClassMethod.class 文件,然后雙擊打開(IDEA 默認(rèn)會(huì)使用 FernFlower 打開字節(jié)碼文件)。
public class InvokeCurrentClassMethod { public InvokeCurrentClassMethod() { } void method1() { } void method2() { this.method1(); } public static void main(String[] args) { (new InvokeCurrentClassMethod()).method1(); } }
“瞪大眼睛仔細(xì)瞧,三妹,this 關(guān)鍵字是不是出現(xiàn)了?”
“哇,真的呢,好神奇啊!”三妹為了配合我的演出,也是十二分的賣力。
“我們可以在一個(gè)類中使用 this 關(guān)鍵字來調(diào)用另外一個(gè)方法,如果沒有使用的話,編譯器會(huì)自動(dòng)幫我們加上。”我對(duì)自己深厚的編程功底充滿自信,“在源代碼中,method2() 在調(diào)用 method1() 的時(shí)候并沒有使用 this 關(guān)鍵字,但通過反編譯后的字節(jié)碼可以看得到?!?/p>
04、調(diào)用當(dāng)前類的構(gòu)造方法
“再來看下面這段代碼。”
public class InvokeConstrutor { InvokeConstrutor() { System.out.println("hello"); } InvokeConstrutor(int count) { this(); System.out.println(count); } public static void main(String[] args) { InvokeConstrutor invokeConstrutor = new InvokeConstrutor(10); } }
“在有參構(gòu)造方法 InvokeConstrutor(int count) 中,使用了 this() 來調(diào)用無參構(gòu)造方法 InvokeConstrutor()?!边@次,我換成了左手的食指,指著屏幕對(duì)三妹說,“this() 可用于調(diào)用當(dāng)前類的構(gòu)造方法——構(gòu)造方法可以重用了。”
“來看一下輸出結(jié)果?!?/p>
hello 10
“真的啊,無參構(gòu)造方法也被調(diào)用了,所以程序輸出了 hello。”三妹看到輸出結(jié)果后不假思索地說。
“也可以在無參構(gòu)造方法中使用 this() 并傳遞參數(shù)來調(diào)用有參構(gòu)造方法?!痹捯魶]落,我就在鍵盤上敲了起來,“來看下面這段代碼?!?/p>
public class InvokeParamConstrutor { InvokeParamConstrutor() { this(10); System.out.println("hello"); } InvokeParamConstrutor(int count) { System.out.println(count); } public static void main(String[] args) { InvokeParamConstrutor invokeConstrutor = new InvokeParamConstrutor(); } }
“再來看一下程序的輸出結(jié)果?!?/p>
10 hello
“不過,需要注意的是,this() 必須放在構(gòu)造方法的第一行,否則就報(bào)錯(cuò)了?!?/p>
05、作為參數(shù)在方法中傳遞
“來看下面這段代碼。”
public class ThisAsParam { void method1(ThisAsParam p) { System.out.println(p); } void method2() { method1(this); } public static void main(String[] args) { ThisAsParam thisAsParam = new ThisAsParam(); System.out.println(thisAsParam); thisAsParam.method2(); } }
“this 關(guān)鍵字可以作為參數(shù)在方法中傳遞,此時(shí),它指向的是當(dāng)前類的對(duì)象?!币徊恍⌒?,半個(gè)小時(shí)過去了,我感到嗓子冒煙,于是趕緊又喝了一口水,潤(rùn)潤(rùn)嗓子后繼續(xù)說道。
“來看一下輸出結(jié)果,你就明白了,三妹?!?/p>
com.itwanger.twentyseven.ThisAsParam@77459877 com.itwanger.twentyseven.ThisAsParam@77459877
“method2() 調(diào)用了 method1(),并傳遞了參數(shù) this,method1() 中打印了當(dāng)前對(duì)象的字符串。main() 方法中打印了 thisAsParam 對(duì)象的字符串。從輸出結(jié)果中可以看得出來,兩者是同一個(gè)對(duì)象?!?/p>
06、作為參數(shù)在構(gòu)造方法中傳遞
“繼續(xù)來看代碼?!?/p>
public class ThisAsConstrutorParam { int count = 10; ThisAsConstrutorParam() { Data data = new Data(this); data.out(); } public static void main(String[] args) { new ThisAsConstrutorParam(); } } class Data { ThisAsConstrutorParam param; Data(ThisAsConstrutorParam param) { this.param = param; } void out() { System.out.println(param.count); } }
“在構(gòu)造方法 ThisAsConstrutorParam() 中,我們使用 this 關(guān)鍵字作為參數(shù)傳遞給了 Data 對(duì)象,它其實(shí)指向的就是 new ThisAsConstrutorParam() 這個(gè)對(duì)象?!?/p>
“this 關(guān)鍵字也可以作為參數(shù)在構(gòu)造方法中傳遞,它指向的是當(dāng)前類的對(duì)象。當(dāng)我們需要在多個(gè)類中使用一個(gè)對(duì)象的時(shí)候,這非常有用。”
“來看一下輸出結(jié)果?!?/p>
10
07、作為方法的返回值
“需要休息會(huì)嗎?三妹”
“沒事的,哥,我的注意力還是很集中的,你繼續(xù)講吧。”
“好的,那來繼續(xù)看代碼?!?/p>
public class ThisAsMethodResult { ThisAsMethodResult getThisAsMethodResult() { return this; } void out() { System.out.println("hello"); } public static void main(String[] args) { new ThisAsMethodResult().getThisAsMethodResult().out(); } }
“getThisAsMethodResult() 方法返回了 this 關(guān)鍵字,指向的就是 new ThisAsMethodResult() 這個(gè)對(duì)象,所以可以緊接著調(diào)用 out() 方法——達(dá)到了鏈?zhǔn)秸{(diào)用的目的,這也是 this 關(guān)鍵字非常經(jīng)典的一種用法。”
“鏈?zhǔn)秸{(diào)用的形式在 JavaScript 代碼更加常見?!睘榱讼蛉米C實(shí)這一點(diǎn),我打開了 jQuery 的源碼。
“原來這么多鏈?zhǔn)秸{(diào)用啊!”三妹感嘆到。
“是的?!蔽尹c(diǎn)點(diǎn)頭,然后指著 getThisAsMethodResult() 方法的返回值對(duì)三妹說,“需要注意的是,this 關(guān)鍵字作為方法的返回值的時(shí)候,方法的返回類型為類的類型?!?/p>
“來看一下輸出結(jié)果?!?/p>
hello
“那么,關(guān)于 this 關(guān)鍵字的介紹,就到此為止了?!蔽一顒?dòng)了一下僵硬的脖子后,對(duì)三妹說,“如果你學(xué)習(xí)勁頭還可以的話,我們順帶把 super 關(guān)鍵字捎帶著過一下,怎么樣?”
“不用了吧,聽說 super 關(guān)鍵字更簡(jiǎn)單,我自己看看就行了,不用你講了!”
“不不不,三妹啊,你得假裝聽一下,不然我怎么向讀者們交差?!?/p>
“噢噢噢噢。”三妹意味深長(zhǎng)地笑了。
08、super 關(guān)鍵字
“super 關(guān)鍵字的用法主要有三種?!?/p>
指向父類對(duì)象;
調(diào)用父類的方法;
super() 可以調(diào)用父類的構(gòu)造方法。
“其實(shí)和 this 有些相似,只不過用意不大相同?!蔽叶似鹚浚具斯具擞趾攘藥状罂?,好渴?!懊慨?dāng)創(chuàng)建一個(gè)子類對(duì)象的時(shí)候,也會(huì)隱式的創(chuàng)建父類對(duì)象,由 super 關(guān)鍵字引用。”
“如果父類和子類擁有同樣名稱的字段,super 關(guān)鍵字可以用來訪問父類的同名字段?!?/p>
“來看下面這段代碼?!?/p>
public class ReferParentField { public static void main(String[] args) { new Dog().printColor(); } } class Animal { String color = "白色"; } class Dog extends Animal { String color = "黑色"; void printColor() { System.out.println(color); System.out.println(super.color); } }
“父類 Animal 中有一個(gè)名為 color 的字段,子類 Dog 中也有一個(gè)名為 color 的字段,子類的 printColor() 方法中,通過 super 關(guān)鍵字可以訪問父類的 color?!?/p>
“來看一下輸出結(jié)果?!?/p>
黑色 白色
“當(dāng)子類和父類的方法名相同時(shí),可以使用 super 關(guān)鍵字來調(diào)用父類的方法。換句話說,super 關(guān)鍵字可以用于方法重寫時(shí)訪問到父類的方法?!?/p>
public class ReferParentMethod { public static void main(String[] args) { new Dog().work(); } } class Animal { void eat() { System.out.println("吃..."); } } class Dog extends Animal { @Override void eat() { System.out.println("吃..."); } void bark() { System.out.println("汪汪汪..."); } void work() { super.eat(); bark(); } }
“瞧,三妹。父類 Animal 和子類 Dog 中都有一個(gè)名為 eat() 的方法,通過 super.eat() 可以訪問到父類的 eat() 方法?!?/p>
等三妹在自我消化的時(shí)候,我在鍵盤上又敲完了一串代碼。
public class ReferParentConstructor { public static void main(String[] args) { new Dog(); } } class Animal { Animal(){ System.out.println("動(dòng)物來了"); } } class Dog extends Animal { Dog() { super(); System.out.println("狗狗來了"); } }
“子類 Dog 的構(gòu)造方法中,第一行代碼為 super(),它就是用來調(diào)用父類的構(gòu)造方法的?!?/p>
“來看一下輸出結(jié)果?!?/p>
動(dòng)物來了 狗狗來了
“當(dāng)然了,在默認(rèn)情況下,super() 是可以省略的,編譯器會(huì)主動(dòng)去調(diào)用父類的構(gòu)造方法。也就是說,子類即使不使用 super() 主動(dòng)調(diào)用父類的構(gòu)造方法,父類的構(gòu)造方法仍然會(huì)先執(zhí)行?!?/p>
public class ReferParentConstructor { public static void main(String[] args) { new Dog(); } } class Animal { Animal(){ System.out.println("動(dòng)物來了"); } } class Dog extends Animal { Dog() { System.out.println("狗狗來了"); } }
“輸出結(jié)果和之前一樣。”
動(dòng)物來了 狗狗來了
“super() 也可以用來調(diào)用父類的有參構(gòu)造方法,這樣可以提高代碼的可重用性?!?/p>
class Person { int id; String name; Person(int id, String name) { this.id = id; this.name = name; } } class Emp extends Person { float salary; Emp(int id, String name, float salary) { super(id, name); this.salary = salary; } void display() { System.out.println(id + " " + name + " " + salary); } } public class CallParentParamConstrutor { public static void main(String[] args) { new Emp(1, "沉默王二", 20000f).display(); } }
“Emp 類繼承了 Person 類,也就繼承了 id 和 name 字段,當(dāng)在 Emp 中新增了 salary 字段后,構(gòu)造方法中就可以使用 super(id, name) 來調(diào)用父類的有參構(gòu)造方法?!?/p>
“來看一下輸出結(jié)果。”
1 沉默王二 20000.0
到此,相信大家對(duì)“使用This完成的工作有哪些”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!