1. 程式人生 > 其它 >深入理解this關鍵字

深入理解this關鍵字

Java中的this關鍵字總是指向呼叫該方法的物件。

  • 在構造器中,引用該構造器正在初始化的物件
  • 在方法中,引用呼叫該方法的物件
package com.ch05;

public class Dog {
    public void jump(){
        System.out.println("正在執行jump方法");
    }
    public void run(){
        Dog d = new Dog();
        d.jump();
//				 this.jump(); 或者 jump();
        System.out.println("正在執行run方法");
    }
}
package com.ch05;

public class DogTest {
    public static void main(String[] args) {
    	Dog dog = new Dog();
        dog.run();
    }
}

在上面的程式中,一共產生了兩個Dog物件,在Dog類的run()方法中,程式建立了一個Dog物件,並使用名為d的引用變數來指向該Dog物件;在DogTest的main()方法中,程式再次建立了一個Dog物件,並使用名為dog的引用變數來指向該Dog物件。

這裡產生了兩個問題。第一個問題:在run()方法中呼叫jump()方法時是否一定需要一個Dog物件?第二個問題:是否一定需要重新建立一個Dog物件?第一個問題的答案是肯定的,因為沒有使用static修飾的成員變數和方法都必須使用物件來呼叫。第二個問題的答案是否定的,因為當程式呼叫run()方法時,一定會提供一個Dog物件,這樣就可以直接使用這個已經存在的Dog物件,而無須重新建立新的Dog物件了。

this可以代表任何物件,當this出現在某個方法體中時,它所代表的物件是不確定的,但它的型別是確定的:它所代表的只能是當前類的例項;只有當這個方法被呼叫時,它所代表的物件才被確定下來:誰在呼叫這個方法,this就代表誰

對於static修飾的方法而言,則可以使用類來直接呼叫該方法,如果在static修飾的方法中使用this關鍵字,則這個關鍵字就無法指向合適的物件。所以,static修飾的方法中不能使用this引用。由於static修飾的方法不能使用this引用,所以static修飾的方法不能訪問不使用static修飾的普通成員,因此Java語法規定:靜態成員不能直接訪問非靜態成員

package com.ch05;

public class StaticAccessNonStatic {
    public void info(){
        System.out.println("Hello");
    }
    public static void main(String[] args){
//        因為main()方法是靜態方法,而info()是非靜態方法
//        呼叫main()方法的是該類本身,而不是該類的物件
//        因此省略的this無法指向有效的物件
        info();
    }
}

編譯上面程式出現如下錯誤: java: 無法從靜態上下文中引用非靜態 方法 info()

Java程式設計時不要使用物件去呼叫static修飾的成員變數、方法,而是應該使用類去呼叫static修飾的成員變數、方法!如果確實需要在靜態方法中訪問另一個普通方法,則只能重新建立一個物件。例如,將上面的info()呼叫改為:new StaticAccessNonStatic().info();


this的其他作用

package com.ch05;

public class ThisInConstructor {
    public int foo;
    public ThisInConstructor(){
//        下面的區域性變數與成員變數同名
        int foo = 0;

        this.foo = 6;
    }

    public static void main(String[] args) {
        System.out.println(new ThisInConstructor().foo); // 6
    }
}

大部分時候,在構造器中訪問其他成員變數和方法時都可以省略this字首,但如果構造器中有一個與成員變數同名的區域性變數,又必須在構造器中訪問這個被覆蓋的成員變數,則必須使用this字首。

package com.ch05;

public class ReturnThis {
    public int age;
    public ReturnThis grow(){
        age++;

        return this;
    }

    public static void main(String[] args) {
        ReturnThis returnThis = new ReturnThis();
        returnThis.grow()
                .grow()
                .grow();

        System.out.println(returnThis.age);
    }
}

如果在某個方法中把this作為返回值,則可以多次連續呼叫同一個方法,從而使得程式碼更加簡潔。