ITEEDU

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()一个应用的基本范例,如此,您不用在建构方法中撰写重复的程序代码。