有時(shí)會(huì)遇到this作為返回值的情況,那么此時(shí)返回的到底是什么呢?
返回的是調(diào)用this所處方法的那個(gè)對象的引用,讀起來有點(diǎn)繞口哈,有沒有想起小學(xué)語文分析句子成份的試題,哈哈。
一點(diǎn)點(diǎn)分析的話,主干是“返回的是引用”;
什么引用呢?“那個(gè)對象的引用”;
哪個(gè)對象呢?“調(diào)用方法的那個(gè)對象”;
調(diào)用的哪個(gè)方法呢?“調(diào)用的是this所位于的方法”;這樣就清楚了。
再總結(jié)一下就是,this作為返回值時(shí),返回的是調(diào)用某方法的對象的引用,這個(gè)方法正是包含“return this;”這行命令的那個(gè)方法;更簡單點(diǎn)說,就是誰調(diào)用返回的就是誰。
為了更清楚、直觀的理解問題,下面以簡單的例子說明。
包human中定義了person類,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
package human; public class person { string name; int age; public person() { } public person(string n, string g) { name = n; gender = g; } //test:this作返回值 person rethis1() { person per = new person( "lu" , "female" ); system.out.println( "rethis1 per:" + per.name); return this ; } person rethis2() { person per = rethis1(); system.out.println( "rethis2 per:" + per.name); return this ; } person rethis3() { name = "ma" ; return this ; } static void equrefer(person per1, person per2) { if (per1 == per2) system.out.println( "per1指向的對象沒有改變,仍與per2指向同一個(gè)對象" ); else system.out.println( "per1指向的對象已改變,與per2指向不同的對象" ); system.out.println( "per1:" + per1.name); system.out.println( "per2:" + per2.name); } public static void main(string[] args) { person per1 = new person( "liu" , "female" ); person per2 = per1; per1 = per1.rethis1(); person.equrefer(per1, per2); per1 = per1.rethis2(); person.equrefer(per1, per2); system.out.println( "調(diào)用rethis3之前,per1.name=" + per1.name); per1 = per1.rethis3(); system.out.println( "調(diào)用rethis3之后,per1.name=" + per1.name); } } |
輸出結(jié)果如下:
1
2
3
4
5
6
7
8
9
10
11
|
rethis1 per:lu per1指向的對象沒有改變,仍與per2指向同一個(gè)對象 per1:liu per2:liu rethis1 per:lu rethis2 per:liu per1指向的對象沒有改變,仍與per2指向同一個(gè)對象 per1:liu per2:liu 調(diào)用rethis3之前,per1.name=liu 調(diào)用rethis3之后,per1.name=ma |
逐句分析執(zhí)行過程:
(1).第1句:person per1 = new person("liu","female");
創(chuàng)建一個(gè)person對象,將name初始化為“liu”,gender初始化為“female”,并讓per1指向該對象。
(2).第2句:person per2 = per1;
定義一個(gè)person類的對象引用,并與per1指向同一個(gè)對象;具體內(nèi)存分配見圖1:
(3).第3句:per1 = per1.rethis1();
由per1調(diào)用rethis1()方法,并將返回值賦給per1;rethis1()方法體內(nèi)定義了一個(gè)局部變量per,并創(chuàng)建一個(gè)對象,由per指向它;具體內(nèi)存分配見圖2:
緊接著輸出rethis1 per:lu;最后返回this,并把返回的值賦給per1。
(4).第4句:person.equrefer(per1, per2);
調(diào)用equrefer(per1,per2)來驗(yàn)證per1的值并未改變;根據(jù)下面的輸出結(jié)果也可知per1仍與per2指向原來的對象,也就是說此時(shí)this的值與per1的值是一致的;也可以說,誰調(diào)用的返回的就是誰。
輸出結(jié)果:
per1指向的對象沒有改變,仍與per2指向同一個(gè)對象
per1:liu
per2:liu
此時(shí)的內(nèi)存圖如圖3:
(5).第5句:per1 = per1.rethis2();
per1調(diào)用rethis2(),由(4)可推測,此時(shí)per1的值也不會(huì)變,是由per1調(diào)用的this所處的方法,所以返回的也是per1;具體來分析的話,rethis2()定義了一個(gè)局部變量per,并給其賦值為rethis1(),也就是說rethis2()調(diào)用了rethis1(),由(3)、(4)可推知,此時(shí)的內(nèi)存結(jié)構(gòu)是下面這樣的:
局部變量per指向的對象與per1是一致的,因?yàn)檎{(diào)用rethis1的對象是per1所指的對象,所以返回值也是per1。
此處的輸出結(jié)果為:
rethis1 per:lu
rethis2 per:liu
(6).第6句:person.equrefer(per1, per2);
驗(yàn)證上面的結(jié)論,per1指向沒變,此時(shí)的內(nèi)存分配圖如圖4所示:
(7).第7、8、9句:
system.out.println("調(diào)用rethis3之前,per1.name=" + per1.name);
per1 = per1.rethis3();
system.out.println("調(diào)用rethis3之后,per1.name=" + per1.name);
per1調(diào)用rethis3();rethis3()中修改了namer的值,由"liu"改為"ma",然后返回this。
調(diào)用前后的內(nèi)存結(jié)構(gòu)分別如圖6、圖7所示:
輸出結(jié)果:
調(diào)用rethis3之前,per1.name=liu
調(diào)用rethis3之后,per1.name=ma
再一次驗(yàn)證了上述的結(jié)論。
關(guān)于為什么使用this,我是這么理解的:由于定義類的時(shí)候尚未創(chuàng)建對象,所以不能確定對象到底叫什么,就用this來統(tǒng)一表示,等到具體調(diào)用時(shí)就可以知道對象的名字了,然后就用對象的引用替換this;所以為了便于記憶,可以理解成誰調(diào)用返回的就是誰。
至于返回this有什么意義,我的理解是:記返回this的方法為a,可能a的方法體中對對象的屬性做了某些操作或調(diào)用了某些方法完成了某些動(dòng)作,總之,做完這些操作后就把原對象的引用返回,返回后的狀態(tài)是對象最新的狀態(tài),可能與對象調(diào)用方法a前不同。
以上這篇淺談java中的this作為返回值時(shí)返回的是什么就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持服務(wù)器之家。
原文鏈接:http://www.cnblogs.com/chanchan/archive/2017/11/10/7812166.html