Thinking in Java(4-2) 深入理解 Java 中的 this 關鍵字與 static 方法
在 Java 程式設計中,this
關鍵字和 static
方法是兩個重要的概念。本篇文章將深入探討它們的用途和特性,並透過範例說明如何在實際程式中應用。
this
關鍵字的用途
多個相同類型的物件調用方法
假設我們有兩個同類型的物件 a
和 b
:
public class BananaPeel {
public static void main(String[] args) {
Banana a = new Banana(),
b = new Banana();
a.peel(1);
b.peel(2);
}
}
在上述程式中,我們如何知道 peel()
方法是被 a
還是 b
調用的呢?
為了以物件導向的方式簡潔地編寫程式,編譯器在幕後做了一些工作:它將「所操作物件的參考」作為第一個參數傳遞給 peel()
方法。
換句話說,編譯器實際上將程式轉換成如下形式:
Banana.peel(a, 1);
Banana.peel(b, 2);
注意:以上寫法只是為了說明原理,實際上我們不能這樣寫。
由於這個參考是由編譯器「偷偷」加上的,因此在方法內部沒有顯式的標識。為此,Java 提供了專門的關鍵字 this
。
this
關鍵字在方法內部代表當前物件的參考。this
只能在方法內使用,與其他物件的參考並無不同。- 在方法內調用另一個物件的方法時,通常不需要使用
this
。
方法內調用其他方法
考慮以下範例:
public class Apricot {
void pick() { /* ... */ }
void pit() { pick(); /* ... */ }
}
在 pit()
方法內,我們可以寫成 this.pick()
,但沒必要,因為編譯器會自動添加 this
。
只有在需要明確指出當前物件時,才需要使用 this
,例如當我們需要返回當前物件的參考時:
public class Leaf {
int i = 0;
Leaf increment() {
i++;
return this;
}
void print() {
System.out.println("i = " + i);
}
public static void main(String[] args) {
Leaf x = new Leaf();
x.increment().increment().increment().print();
}
} /* Output:
i = 3
*/
在上述程式中,increment()
方法返回 this
,使我們可以鏈式調用該方法。
將當前物件傳遞給其他方法
當我們需要將當前物件傳遞給其他方法時,this
也非常有用:
class Person {
public void eat(Apple apple) {
Apple peeled = apple.getPeeled();
System.out.println("Yummy");
}
}
class Peeler {
static Apple peel(Apple apple) {
// ... remove peel
return apple; // Peeled
}
}
class Apple {
Apple getPeeled() { return Peeler.peel(this); }
}
public class PassingThis {
public static void main(String[] args) {
new Person().eat(new Apple());
}
} /* Output:
Yummy
*/
在這個範例中,Apple
物件透過 this
將自己傳遞給 Peeler.peel()
方法。
在建構子中調用其他建構子
在建構子中,如果我們使用 this
並附帶參數列表,會產生對符合該參數列表的另一個建構子的明確調用。
public class Flower {
int petalCount = 0;
String s = "initial value";
Flower(int petals) {
petalCount = petals;
print("Constructor w/ int arg only, petalCount= "
+ petalCount);
}
Flower(String ss) {
print("Constructor w/ String arg only, s = " + ss);
s = ss;
}
Flower(String s, int petals) {
this(petals);
//! this(s); // Can't call two!
this.s = s; // Another use of "this"
print("String & int args");
}
Flower() {
this("hi", 47);
print("default constructor (no args)");
}
void printPetalCount() {
//! this(11); // Not inside non-constructor!
print("petalCount = " + petalCount + " s = "+ s);
}
public static void main(String[] args) {
Flower x = new Flower();
x.printPetalCount();
}
} /* Output:
Constructor w/ int arg only, petalCount= 47
String & int args
default constructor (no args)
petalCount = 47 s = hi
*/
注意事項:
- 可以使用
this
調用另一個建構子,但不能同時調用多個。 - 必須將建構子的調用放在當前建構子的第一行,否則編譯器會報錯。
- 在非建構子的方法中,不能使用
this
調用建構子。
static
的概念
static
方法是沒有this
的方法,只能訪問其他static
方法和static
屬性。static
方法可以在沒有任何物件實例的情況下,透過類別本身調用。- Java 不允許使用全域方法,但我們可以在類別中定義
static
方法,來模擬全域方法的效果。
範例:
public class StaticExample {
static int staticValue = 5;
static void staticMethod() {
System.out.println("Static method called. staticValue = " + staticValue);
}
public static void main(String[] args) {
StaticExample.staticMethod();
}
} /* Output:
Static method called. staticValue = 5
*/
在這個範例中,我們直接使用類別名調用 staticMethod()
,而不需要創建物件實例。
總結
this
關鍵字在 Java 中扮演著重要的角色,使我們能夠在物件導向的程式設計中精確地操作和傳遞當前物件。它在方法和建構子中都有廣泛的應用。
另一方面,static
方法和屬性則提供了在沒有物件實例的情況下,共享資料和行為的方式。理解這兩個概念有助於我們更有效地編寫 Java 程式。
Comments ()