1. 程式人生 > >java學習筆記-this關鍵字

java學習筆記-this關鍵字

轉自:https://blog.csdn.net/jiner_x/article/details/78750579

this關鍵字代表自身,在程式中主要的用途

1.用this在自身的構造方法內部呼叫其他的構造方法

2.用this代表自身類的物件

—直接使用this

—使用this引用成員變數

—使用this呼叫成員方法

this的值是當前物件的引用,只能用它來呼叫屬於當前物件的方法或者使用this引用成員變數和區域性變數重名

看一個例子:

public Class Student{

String name;//定義一個成員變數name

private void SetName(String name){//定義一個引數(區域性變數)name

this.name=name;//將區域性變數的值傳遞給成員變數

}

}

應用一:引用成員變數
 如上面這段程式碼中,有一個成員變數name,同時在方法中有一個形式引數,名字也是name,然後在方法中將形式引數name的值傳遞給成員變數name,Java編譯器它是怎麼判斷的呢?到底是將形式引數name的值傳遞給成員變數name,還是反過來將成員變數name的值傳遞給形式引數name呢?也就是說,兩個變數名字如果相同的話,那麼Java如何判斷使用哪個變數?此時this這個關鍵字就起到作用了。this這個關鍵字其代表的就是物件中的成員變數或者方法。也就是說,如果在某個變數前面加上一個this關鍵字,其指的就是這個物件的成員變數或者方法,而不是指成員方法的形式引數或者區域性變數。為此在上面這個程式碼中,this.name代表的就是物件中的成員變數,又叫做物件的屬性,而後面的name則是方法的形式引數,程式碼this.name=name就是將形式引數的值傳遞給成員變數。這就是上面這個程式碼的具體含義。
 一般情況下,在Java語言中引用成員變數或者成員方法都是以物件名.成員變數或者物件名.成員方法的形式。不過有些程式設計師即使在沒有相同變數的時候,也喜歡使用this.成員變數的形式來引用變數,這主要是從便於程式碼的閱讀考慮的。一看到這個this關鍵字就知道現在引用的變數是成員變數或者成員方法,而不是區域性變數。這無形中就提高了程式碼的閱讀性。不過話說回來,這是this關鍵字在Java語言中的最簡單的應用。從這個應用中,我們可以看出this關鍵字其代表的就是物件的名字。
 其實如果是區域性變數的話,也是相同的道理。如在上面的程式碼中,name不是形式引數,而是一個區域性變數。此時Java也會遇到相同的疑惑,即變數名name代表的到底是區域性變數還是形式引數?name=name到底代表的是什麼含義?根據區域性變數的作用域,在方法內部,如果區域性變數與成員變數同名的話,那麼是以區域性變數為準。可是在name=name這個賦值語句中,將區域性變數的值賦值給自己,顯然並不是很合適。根據程式碼的含義,本來的意思應該是將區域性變數賦值給成員變數。為了更清晰的表達這個含義,為此最好採用如下的書寫格式this.name=name。這裡的this關鍵字含義就是物件名student,為此this.name就表示student.name。

應用二:呼叫類的構造方法
public class Student { //定義一個類,類的名字為student。
 public Student() { //定義一個方法,名字與類相同故為構造方法
  this(“Hello!”);
 }
 public Student(String name) { //定義一個帶形式引數的構造方法
 }
}
  this關鍵字除了可以呼叫成員變數之外,還可以呼叫構造方法。在一個Java類中,其方法可以分為成員方法和構造方法兩種。構造方法是一個與類同名的方法,在Java類中必須存在一個構造方法。如果在程式碼中沒有顯示的體現構造方法的話,那麼編譯器在編譯的時候會自動新增一個沒有形式引數的構造方法。這個構造方法跟普通的成員方法還是有很多不同的地方。如構造方法一律是沒有返回值的,而且也不用void關鍵字來說明這個構造方法沒有返回值。而普通的方法可以有返回值、也可以沒有返回值,程式設計師可以根據自己的需要來定義。不過如果普通的方法沒有返回值的話,那麼一定要在方法定義的時候採用void關鍵字來進行說明。其次構造方法的名字有嚴格的要求,即必須與類的名字相同。也就是說,Java編譯器發現有個方法與類的名字相同才把其當作構造方法來對待。而對於普通方法的話,則要求不能夠與類的名字相同,而且多個成員方法不能夠採用相同的名字。在一個類中可以存在多個構造方法,這些構造方法都採用相同的名字,只是形式引數不同。Java語言就憑形式引數不同來判斷呼叫那個構造方法。
 在上面這段程式碼中,定義了兩個構造方法,一個帶引數,另一個沒有帶引數。構造方法都不會有返回值,不過由於構造方法的特殊性,為此不必要在構造方法定義時帶上void關鍵字來說明這個問題。在第一個沒有帶引數的構造方法中,使用了this(“Hello!”)這句程式碼,這句程式碼表示什麼含義呢?在構造方法中使this關鍵字表示呼叫類中的構造方法。如果一個類中有多個構造方法,因為其名字都相同,跟類名一致,那麼這個this到底是呼叫哪個構造方法呢?其實,這跟採用其他方法引用構造方法一樣,都是通過形式引數來呼叫構造方法的。如上例中,this關鍵字後面加上了一個引數,那麼就表示其引用的是帶引數的構造方法。如果現在有三個構造方法,分別為不帶引數、帶一個引數、帶兩個引數。那麼Java編譯器會根據所傳遞的引數數量的不同,來判斷該呼叫哪個構造方法。從上面示例中可以看出,this關鍵字不僅可以用來引用成員變數,而且還可以用來引用構造方法。
 不過如果要使用這種方式來呼叫構造方法的話,有一個語法上的限制。一般來說,利用this關鍵字來呼叫構造方法,只有在無引數構造方法中第一句使用this呼叫有引數的構造方法。否則的話,翻譯的時候,就會有錯誤資訊。這跟引用成員變數不同。如果引用成員變數的話,this關鍵字是沒有位置上的限制的。如果不熟悉這個限制的話,那麼還是老老實實的採用傳統的構造方法呼叫方式為好。雖然比較麻煩,但是至少不會出錯。
應用三:返回物件的值
 this關鍵字除了可以引用變數或者成員方法之外,還有一個重大的作用就是返回類的引用。如在程式碼中,可以使用return this,來返回某個類的引用。此時這個this關鍵字就代表類的名稱。如程式碼在上面student類中,那麼程式碼代表的含義就是return student。可見,這個this關鍵字除了可以引用變數或者成員方法之外,還可以作為類的返回值,這才是this關鍵字最引人注意的地方。

為什麼靜態成員、靜態方法中不能用this和super關鍵字

1.     在靜態方法中是不能使用this預定義物件引用的,即使其後邊所操作的也是靜態成員也不行.
因為this代表的是呼叫這個函式的物件的引用,而靜態方法是屬於類的,不屬於物件,靜態方法成功載入後,物件還不一定存在

2.     在問題之前先講super的用法:
1).super的用法跟this類似,this代表對本類物件的引用,指向本類已經建立的物件;而super代表對父類物件的引用,指向父類物件;
2).靜態優先於物件存在;
3).由上面的1.和2.知:
因為靜態優先於物件存在,所以方法被靜態修飾之後方法先存在,而方法裡面要用到super指向的父類物件,但是所需的父類引用物件晚於該方法出現,也就是super所指向的物件沒有,當然就會出錯。
綜上,靜態方法中不可以出現super關鍵字。

3. 首先你要明白物件和類的區別。
this和super是屬於物件範疇的東西,而靜態方法是屬於類範疇的東西
所有的成員方法,都有一個預設的的引數this(即使是無參的方法),只要是成員方法,編譯器就會給你加上this這個引數如:
Class A中
void method1(){}實際上是這樣的--------> void method1(A this)
void method2(int x){}實際上是這樣的--------> void method2(A this, intx)
而靜態方法與物件無關,根本不能把物件的引用傳到方法中,所以不能用this

4.在一個類中定義一個方法為static,則為靜態方法,那就是說,無需本類的物件即可呼叫此方法,呼叫一個靜態方法就是“類名.方法名”

既然"無需本類的物件即可呼叫靜態方法",而this和super關鍵字都是用於本類物件的-----呼叫靜態方法無需本類的物件這句話很清楚表明:靜態方法中不能用this和super關鍵字

5. 靜態方法是存放在記憶體中的資料段裡,this和super呼叫的是堆空間裡的應用物件不能呼叫資料段區域裡的資料,因此靜態方法中不能用this和super關鍵字

6. 靜態方法和靜態類不屬於單個物件,而是類的所有物件共享使用
而this代表當前物件

 7.   東西只屬於類,不屬於任何物件,所以不能用THIS和SUPER。