Java培訓教程之this關鍵字講解

千鋒武漢發表於2021-06-21

  前面小節中,類在定義成員方法時,區域性變數和成員變數可以重名,但此時不能訪問成員變數。為避免這種情形,Java提供了this關鍵字,表示當前物件,指向呼叫的物件本身。接下來演示this的本質,如例4-1所示。

  例4-1 TestThis.java

  1 class Person {

  2 public void equals(Person p) {

  3 System.out.println(this); // 列印this的地址

  4 System.out.println(p); // 列印物件地址

  5 if (this == p) // 判斷當前物件與this是否相等

  6 System.out.println("相等");

  7 else

  8 System.out.println("不相等");

  9 }

  10 }

  11 public class TestThis {

  12 public static void main(String[] args) {

  13 Person p1 = new Person();

  14 Person p2 = new Person();

  15 p1.equals(p1);

  16 p1.equals(p2);

  17 }

  18 }

  程式的執行結果如圖4.1所示。

圖片1

  圖4.1 例4-1執行結果

  在圖4.1中,從程式執行結果可發現,關鍵字this和呼叫物件p1的值相等,都儲存了指向堆記憶體空間的地址,也就是說,this就是呼叫物件本身。因此,呼叫物件p1的this與p2物件不相等。

  this關鍵字在程式中主要有三種用法,下面來分別講解各種用法:

   1.使用this呼叫類中的屬性

  this關鍵字可以明確呼叫類的成員變數,不會與區域性變數名發生衝突。接下來演示this呼叫屬性,如例4-2所示。

  例4-2 TestThisRefAttr.java

  1 class Person {

  2 private String name; // 宣告姓名私有屬性

  3 private int age; // 宣告年齡私有屬性

  4 public Person(String name, int age) {

  5 this.name = name; // 明確表示為類中的name屬性賦值

  6 this.age = age; // 明確表示為類中的age屬性賦值

  7 }

  8 public void say() { // 定義顯示資訊的方法

  9 System.out.println("姓名:"+this.name+",年齡:"+this.age);

  10 }

  11 }

  12 public class TestThisRefAttr {

  13 public static void main(String[] args) {

  14 Person p = new Person("張三", 18);

  15 p.say();

  16 }

  17 }

  程式的執行結果如圖4.2所示。

圖片2

  圖4.2 例4-2執行結果

  例4-2中,構造方法的形參與成員變數同名,使用this明確呼叫成員變數,避免了與區域性變數產生衝突。

   2.使用this呼叫成員方法

  this既然可以訪問成員變數,那麼也可以訪問成員方法,如例4-3所示。

  例4-3 TestThisRefFun.java

  1 class Person {

  2 private String name; // 宣告姓名私有屬性

  3 private int age; // 宣告年齡私有屬性

  4 public Person(String name, int age) {

  5 this.name = name; // 明確表示為類中的name屬性賦值

  6 this.age = age; // 明確表示為類中的age屬性賦值

  7 }

  8 public void say() { // 定義顯示資訊的方法

  9 System.out.println("姓名:"+this.name+",年齡:"+this.age);

  10 this.log("Person.say"); // this呼叫成員方法

  11 }

  12 public void log(String msg) {

  13 System.out.println("日誌記錄:呼叫"+msg);

  14 }

  15 }

  16 public class TestThisRefFun {

  17 public static void main(String[] args) {

  18 Person p = new Person("張三", 18);

  19 p.say();

  20 }

  21 }

  程式的執行結果如圖4.3所示。

圖片3

  圖4.3 例4-3執行結果

  例4-3中,在say()方法中明確使用this呼叫log()成員方法。另外,此處的this可以省略,但建議不要省略,使程式碼更加清晰。

   3.使用this呼叫構造方法

  構造方法是在例項化時被自動呼叫的,因此不能直接像呼叫成員方法一樣去呼叫構造方法,但可以使用this([實參列表])的方式呼叫其他的構造方法,如例4-4所示。

  例4-4 TestThisRefConstructor.java

  1 class Person {

  2 private String name; // 宣告姓名私有屬性

  3 private int age; // 宣告年齡私有屬性

  4

  5 public Person() {

  6 System.out.println("呼叫無參構造方法");

  7 }

  8 public Person(String name, int age) {

  9 this(); // 呼叫無參建構函式

  10 System.out.println("呼叫有參建構函式");

  11 this.name = name; // 明確表示為類中的name屬性賦值

  12 this.age = age; // 明確表示為類中的age屬性賦值

  13 }

  14 public void say() { // 定義顯示資訊的方法

  15 System.out.println("姓名:"+this.name+",年齡:"+this.age);

  16 }

  17 }

  18 public class TestThisRefConstructor {

  19 public static void main(String[] args) {

  20 Person p = new Person("張三", 18);

  21 p.say();

  22 }

  23 }

  程式的執行結果如圖4.4所示。

圖片4

  圖4.4 例4-4執行結果

  例4-4中,例項化物件時,呼叫了有參構造方法,在該方法中透過this()呼叫了無參構造方法。因此,執行結果中顯示兩個構造方法都被呼叫了。

  在使用this呼叫構造方法時,還需注意:在構造方法中,使用 this呼叫構造方法的語句必須位於首行,且只能出現一次,如例4-5所示。

  例4-5 TestThisRefConstructor01.java

  1 class Person {

  2 private String name; // 姓名

  3 private int age; // 年齡

  4 public Person() {

  5 System.out.println("呼叫無參構造方法");

  6 }

  7 public Person(String name, int age) {

  8 System.out.println("呼叫有參建構函式");

  9 this.name = name;

  10 this.age = age;

  11 this(); // 呼叫無參建構函式

  12 }

  13 public void say() {

  14 System.out.println("姓名:"+this.name+",年齡:"+this.age);

  15 }

  16 }

  程式的執行結果如圖4.5所示。

圖片5

  圖4.5 例4-5執行結果

  在圖4.5中,編譯報錯並提示“對this的呼叫必須是構造器中的第一個語句”。因此在使用this()呼叫構造方法必須位於構造方法的第一行。

  另外,this呼叫構造方法時,一定要留一個構造方法作為出口,即至少存在一個構造方法不使用this呼叫其他構造方法,如例4-6所示。

  例4-6 TestThisRefConstructor02.java

  1 class Person {

  2 private String name; // 姓名

  3 private int age; // 年齡

  4 public Person() {

  5 this(null, 0); // 呼叫有參建構函式

  6 System.out.println("呼叫無參構造方法");

  7 }

  8 public Person(String name, int age) {

  9 this(); // 呼叫無參建構函式

  10 System.out.println("呼叫有參建構函式");

  11 this.name = name;

  12 this.age = age;

  13 }

  14 public void say() {

  15 System.out.println("姓名:"+this.name+",年齡:"+this.age);

  16 }

  17 }

  程式的執行結果如圖4.6所示。

圖片6

  圖4.6 例4-6執行結果

  在圖4.6中,編譯報錯並提示“遞迴構造器呼叫”。因此,在構造方法互相呼叫時,一定要預留一個出口,一般將無參構造方法作為出口,即在無參構造方法中不再去呼叫其他構造方法。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31548651/viewspace-2777551/,如需轉載,請註明出處,否則將追究法律責任。

相關文章