當一個對象創建后,Java虛擬機(JVM)就會給這個對象分配一個引用自身的指針,這個指針的名字就是 this。
因此,this只能在類中的非靜態方法中使用,靜態方法和靜態的代碼塊中絕對不能出現this,並且this只和特定的對象關聯,而不和類關聯,同一個類的不同對象有不同的this。
1、 使用this來區分當前對象。
Java中為解決變量的命名沖突和不確定性問題,引入關鍵字this代表其所在方法的當前對象的引用:
1) 構造方法中指該構造器所創建的新對象;
2) 方法中指調用該方法的對象;
3) 在類本身的方法或構造器中引用該類的實例變量(全局變量)和方法。
this只能用在構造器或者方法中,用於獲得調用當前的構造器方法的對象引用。可以和任何的對象引用一樣來處理這個this對象。
說明:
(1)當實例變量和局部變量重名,JAVA平台會按照先局部變量、后實例變量的順序尋找。即,方法中使用到的變量的尋找規律是先找局部變量,再找實例變量。如果沒用找到,將會有一個編譯錯誤而無法通過編譯。
(2)如果使用this.a,則不會在方法(局部變量)中尋找變量a,而是直接去實例變量中去尋找,如果尋找不到,則會有一個編譯錯誤。
(3)在一個方法內,如果沒有出現局部變量和實例變量重名的情況下,是否使用this關鍵字是沒有區別的。
(4)在同一個類中,Java普通方法的互相調用可以省略this+點號,而直接使用方法名+參數。因為Java編譯器會幫我們加上。
2、 在構造器中使用this來調用對象本身的其他構造器。
在構造器中使用this([args_list]);可以調用對象本身的其他的構造器。直接使用this()加上類構造器所需要的參數。就可以調用類本身的其他構造器了。如果類中有多個其他構造器定義,系統將自動根據this()中的參數個數和類型來找出類中相匹配的構造器。
注意: 在構造器中可以通過this()方式來調用其他的構造器。但在一個構造器中最多只能調用一個其他的構造器。並且,對其他構造器的調用動作必須放在構造器的起始處(也就是構造器的首行),否則編譯的時候將會出現錯誤,另外不能在構造器以外的地方以這種方式調用構造器。
3、 this關鍵字還有一個重大的作用就是返回類的引用。如在代碼中,可以使用return this來返回某個類的引用。此時,這個this關鍵字就代表類的名稱。
例1. 把this作為參數傳遞
當你要把自己作為參數傳遞給別的對象時,也可以用this。如:
public class A{ public A(){ new B(this).print(); } public void print(){ System.out.println("From A!"); } public static void main(String[] args) { new A(); } } public class B{ A a; public B(A a){ this.a = a; } public void print(){ a.print(); System.out.println("From B!"); } }
運行結果:From A!
From B!
在這個例子中,對象A的構造函數中,用new B(this)把對象A自己作為參數傳遞給了對象B的構造函數。
例2. 注意匿名類和內部類中的中的this。
有時候,我們會用到一些內部類和匿名類,如事件處理。當在匿名類中出現this時,這個this則指的是匿名類或內部類本身。這時如果我們要使用外部類的方法和變量的話,則應該加上外部類的類名。如下面這個例子:
public class C { int i = 1; public C(){ Thread thread = new Thread(){ public void run(){ for(;;){//表示是死循環 C.this.run();//調用外部方法run() try { sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } };//注意這里有分號; thread.start(); } public void run(){ System.out.println("i = " + i); i++; } public static void main(String[] args) throws Exception { new C(); } }
運行結果:每一秒產生一個數:1,2,3 ……
在上面這個例子中, thread 是一個匿名類對象,在它的定義中,它的 run 函數里用到了外部類的 run 函數。這時由於函數同名,直接調用就不行了。這時有兩種辦法,一種就是把外部的 run 函數換一個名字,但這種辦法對於一個開發到中途的應用來說是不可取的。那么就可以用這個例子中的辦法用外部類的類名加上 this 引用來說明要調用的是外部類的方法 run。
例3、this關鍵字最大的作用是,讓類的一個方法,訪問該類的另一個方法或者屬性。
先看一個不好的例子:
public class Baby{ public void wakeUp(){ System.out.println("寶寶醒啦"); } public void eat(){ Baby baby = new Baby(); baby.wakeUp(); System.out.println("吃東西"); } }
這樣不符合邏輯。這就相當於本對象的eat方法,需要調用另一個對象的wakeUp方法。
我們看這個例子:
public class Baby{ public void wakeUp(){ System.out.println("寶寶醒啦"); } public void eat(){ this.wakeUp(); System.out.println("吃東西"); } }
這樣就符合邏輯了。自己的eat方法,還需要自己的一個wakeUp方法。
java允許同一個對象的方法直接調用該對象的屬性或者方法,所以this可以省略。
注意:java中為什么在static中不能使用this關鍵字
Static方法是類方法,先於任何的實例(對象)存在。即Static方法在類加載時就已經存在了,但是對象是在創建時才在內存中生成。而this指代的是當前的對象
在方法中定義使用的this關鍵字,它的值是當前對象的引用.也就是說你只能用它來調用屬於當前對象的方法或者使用this處理方法中成員變量和局部變量重名的情況.
而且,更為重要的是this和super都無法出現在static 修飾的方法中,static 修飾的方法是屬於類的,該方法的調用者可能是一個類,而不是對象.如果使用的是類來調用而不是對象,
則 this就無法指向合適的對象.所以static 修飾的方法中不能使用this.