this 的表示范圍
this 指的是它所在的直接所在的類。
例如:
public class MyClass{
int num;
public MyClass(int num){
this.num = num;
}
}
在初始化中,傳入的變量名與 MyClass 類的類變量名一致。如果直接:
num = num;
這樣是得不到預期的效果的。
這里的 this.num 可以理解為 MyClass.num ,但又不是 MyClass.num 。因為程序在運行的時候,會有一個 MyClass 類的實例對象。這個 this 指的是實例化的對象,而 MyClass.num 則指的是靜態的類。
Android 中,在給 MainActivity 類的按鈕設置點擊事件的時候:
btnSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"this is a toast",Toast.LENGTH_SHORT).show();
}
});
這里用到了 MainActivity.this ,如果直接傳入 this 則是錯的。
但同時你又會發現,如果你不是在這個new View.OnClickListener()
里面寫 Toast ,就不用寫成MainActivity.this
,而是直接寫成:
Toast.makeText(this,"this is another toast",Toast.LENGTH_SHORT).show();
怎么會有兩種寫法?
第一種寫法是因為這里的new View.OnClickListener()
創建了一個對象,View.OnClickListener()
是一個接口,那么自然就得有一個類來實現這個接口,這里是一個匿名類。也就是說,第一種寫法是在 MainActivity 類的內部的一個類里面寫的 Toast 。那么如果直接使用 this ,這時它指向的是這個匿名類,因為 this 的直接所在類是這個匿名類。
第二種寫法是因為這是直接寫在 MainActivity 這個類的方法里面的,這行代碼沒有再被一個類所包含, MainActivity 是它的直接上層類。
傳入 Activity 而不是 Context ?
到這里還有一個疑問,那就是 Toast 類的這個 makeText 所要求的參數:
public static Toast makeText(Context context, CharSequence text, @Duration int duration)
這里接收的是 Context ,而我們傳入的是 Activity 。
在 Activity官方文檔 可以看到:
Activity 是 Context 的間接子類,所以可以直接傳入 Activity 。
順便,我們再來看看我們經常看到的一個AppCompatActivity
類,也就是我們每次創建新的 Activity 的時候,Android Studio 自動幫我們繼承的類。我以前曾經很好奇:為什么不是直接繼承 Activity 類?
這個 AppCompatActivity 是 Activity 的間接子類!它是一種向下兼容的 Activity ,可以將在 Android 2.1系統之后 Activity 增加的內容可以在 Android 2.1上正確執行。只要你編寫程序的時候,在build.gradle
的dependencies
里添加遠程依賴庫,例如:
compile 'com.android.support:appcompat-v7:25.1.0'
這個通常是 Android Studio 自動添加的,我們只需要放心的使用 AppCompatActivity 就行了。