From Gossip@Openhome

Java Gossip: 關於 this

考慮下面這個類別:
  • Ball.java
 public class Ball { 
private double radius;
private String name;

public Ball() {
this(0.0, "no name");
}

public Ball(double radius, String name) {
this.radius = radius;
this.name = name;
}

public double getRadius() {
return radius;
}

public double getVolumn() {
return (4 / 3 * Math.PI * radius * radius * radius);
}

public String getName() {
return name;
}

public void setRadius(double radius) {
this.radius = radius;
}

public void setName(String name) {
this.name = name;
}
}

當使用這個類別新增兩個物件ball1與ball2時,ball1與ball2會各自擁有自己的radius與name資料成員,然而方法成員在記憶 體中卻只有一份。

當使用ball1.getName()與b2.getName()方法取回name的名稱時,即然類別的方法成員只有一份,getName()如何知 道它傳回的name是ball1物件的,還是ball2物件的呢?

其實您使用物件名稱來呼叫方法成員時,程式會將物件的參考告知方法成員,而在方法中,一個類別資料成員其實會隱含一個this參考,這個this參 考會儲存傳遞進來的物件參考,當您呼叫getRadius()函式時,其實相當於執行:
public double getRadius() {
    return this.radius;
}

當ball1呼叫getRadius()方法時,this所參考的就是ball1所參考的物件,而使用ball2呼叫 getRadius()方法時,this所參考的就是ball2所參考的物件,所以getRadius()可以正確的得知該傳回哪一個物件的radius 資料。

每一個類別的方法成員都會隱含一個this參考,用來指向呼叫它的物件,當您在方法中使用資料成員時,都會隱含的使用this指標,當然您也可以明確的指定,例如在函式定義時使用:
public Ball(double radius, String name) {
    this.radius = radius;
    this.name = name;
}

參數名稱與資料成員名稱相同時,為了識別是參數或是資料成員,我們必須明確的使用this參考來指定,但如果是下例則不用:
public Ball(double r, String n) {
    radius = r;  // 實際等於this.radius = r;
    name = n;    // 實際等於this.name = n;
}
 

再介紹一個this參考的使用時機:當物件需要得知自己的記憶體位址時。這種例子很多,例如告知某個函式處理對象為自己、或在Java視窗程式中,註冊物件本身為事件處理者,例如下面這個簡單的Java程式中就有使用到this參考:
public class GUIExample extends JFrame
                             implements MouseListener {
    // ....
    // 實作事件處理的物件為自已
        addMouseListener(this);   
    // ....
 
    // ==  滑鼠事件實作 ==
    public void mouseEntered(MouseEvent e) {
        // .....
    }
    // ....
}
 
這只是一個示範,告知您this參考的用法,如果日後您學到Java視窗程式的事件處理,相信這樣的例子您會看到不少。

this除了上面的用法之外,還有一種可以帶參數的用法,主要是用於類別中呼叫建構方法,而避免直接以建構方法的名稱來呼叫,例如:
public class Ball {
    private String name;
 
    public Ball() {
        this("No name");
        ....
    }
 
    public Ball(String name) {
        this.name = name;
        ....
    }
}
 

當使用無參數的建構方法時,它會呼叫有參數的建構方法,這是this()一個應用的基本範例,如此,您不用在建構方法中撰寫重覆的程式碼。