前言
面向?qū)ο蟮恼Z言中大多有關(guān)鍵字this娱两,用于表示對象本身。但不同語言對于其支持的用法不盡相同邑茄。
Java
根據(jù)《Thinking in Java》中提到的蛋叼,Java中關(guān)于this的用法主要就是三種:
- this用于傳遞當(dāng)前對象
- this用作調(diào)用成員變量
- this用于調(diào)用構(gòu)造方法
this用于傳遞當(dāng)前對象
- 傳遞到方法參數(shù)中
這是最為常見的用法之一,在某個類中需要將其傳遞給某一個方法中部蛇,例如:
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;
}
}
class Apple{
Apple getPeeled(){
return Peeler.peel(this);
}
}
public class This{
public static void main(String args[]){
new Person().eat(new Apple());
}
}
在該例子中摊唇,Apple類的對象通過this將自己的對象傳遞給Peeler.peel方法,在該方法中可以獲得Apple對象并對其進(jìn)行處理涯鲁。
- 作為方法返回值
除了作為方法參數(shù)巷查,this表示的對象還可以作為返回值,在鏈?zhǔn)秸{(diào)用或建造者設(shè)計模式中均有應(yīng)用:
public class Tool{
class Builder{
setA(A a){
//...
return this;
}
setB(B b){
//...
return this;
}
}
}
在上面例子中是建造者設(shè)計模式的局部代碼抹腿,其中的內(nèi)部類Builder擁有多個方法岛请,每個方法的返回值均是this,可以讓調(diào)用者實現(xiàn)’鏈?zhǔn)健{(diào)用警绩,即
new Builder()
.setA(a)
.setB(b);
this用于調(diào)用成員變量
對于JavaBean類崇败,其中的成員變量與方法形參可能同名,為了將其區(qū)分,可以通過this:
class Demo{
String str;
public void setStr(String str){
this.str = str
}
}
this用于調(diào)用構(gòu)造方法
class Demo{
Demo(){
this("default");
}
Demo(String str){
//xxx
}
}
Kotlin
在Kotlin中this表達(dá)的含義會更為廣泛一些后室,除了表示類對象缩膝,還是表示接受者,具體來說:
- 在類的成員中岸霹,this 指的是該類的當(dāng)前對象疾层。
- 在擴(kuò)展函數(shù)或者帶有接收者的函數(shù)字面值中, this 表示在點左側(cè)傳遞的 接收者 參數(shù)松申。
標(biāo)簽限定符
如果 this 沒有限定符云芦,它指的是最內(nèi)層的包含它的作用域。要引用其他作用域中的 this贸桶,需要使用標(biāo)簽限定符舅逸。
要訪問來自外部作用域的this(一個類 或者擴(kuò)展函數(shù), 或者帶標(biāo)簽的帶有接收者的函數(shù)字面值)我們使用this@label皇筛,其中 @label 是一個代指 this 來源的標(biāo)簽琉历。
class A { // 隱式標(biāo)簽 @A
inner class B { // 隱式標(biāo)簽 @B
fun Int.foo() { // 隱式標(biāo)簽 @foo
val a = this@A // A 的 this
val b = this@B // B 的 this
val c = this // foo() 的接收者,一個 Int
val c1 = this@foo // foo() 的接收者水醋,一個 Int
val funLit = lambda@ fun String.() {
val d = this // funLit 的接收者
}
val funLit2 = { s: String ->
// foo() 的接收者旗笔,因為它包含的 lambda 表達(dá)式
// 沒有任何接收者
val d1 = this
}
}
}
}