Java關鍵字this、super使用總結

1、this關鍵字

Java關鍵字this只能用於成員方法體內,它是一個系統隱含的指針且被自動附加在非靜態的成員方法參數列表中。當一個對象被建立後,Java虛擬機(JVM)就會給這個對象分配一個引用自身的指針,這個指針的名字就是this。 java

當前時刻,哪一個對象調用該函數,那麼this就指向當前調用該函數的對象(this也能夠理解爲當前(上下文)對象),系統會自動在該函數的參數列表中添加一個隱藏的this指針,而且把調用該函數的對象的地址值賦給this指針,這樣一來,在函數的內部經過this就能夠訪問當前正在調用該函數的對象的成員(包括成員變量、成員方法)。函數

所以,this只能在類中的非靜態方法中使用,靜態方法和靜態的代碼塊中絕對不能出現this(指針),這在「Java關鍵字static、final使用總結」 一文中給出了明確解釋。
而且this只和特定的對象關聯,而不和類關聯,同一個類的不一樣對象有不一樣的this。下面給出一個使用this的綜合實例,以便說明問題:
this

package org.leizhimin;

public class Test6 {
    private intnumber;
    private String username;
    private Stringpassword;
    private intx = 100;
    
    public Test6(int n) {
        number =n;//這個還能夠寫爲:this.number=n;
                  //this表明當前時刻正在建立的對象
    }

    public Test6(int i, String username, String password) {
        //成員變量和參數同名,成員變量被屏蔽,用「this.成員變量」的方式訪問成員變量。
        this.username = username;
        this.password = password;
    }

    //默認不帶參數的構造方法
    public Test6() {
        this(0, "未知", "空"); //經過this調用另外一個構造方法
                              //即本類的第二個構造方法
    }

    public Test6(String name) {
        this(1, name, "空"); //經過this調用另外一個構造方法
                             //即本類的第二個構造方法
    }

    public static void main(String args[]) {
        Test6 t1= new Test6();
        Test6 t2 =new Test6("遊客");
        t1.outinfo(t1); 
        t2.outinfo(t2);
    }
    
    private void outinfo(Test6 t) {
        System.out.println("-----------");
        System.out.println(t.number);
        System.out.println(t.username);
        System.out.println(t.password);
        f();//這個能夠寫爲:this.f();
 
    }

    private void f() {
        //局部變量與成員變量同名,成員變量被屏蔽,用「this.成員變量」的方式訪問成員變量。
        int x;
        x = this.x++;
        System.out.println(x);
        System.out.println(this.x);
    }
    
    //返回當前實例的引用
    private Test6 getSelf() {
        return this;
    }
}

 運行結果以下:
-----------
0
未知

100
101
-----------
0
遊客

100
101
spa

看着上面的例子,總結在以下三個地方會用到this
①經過this調用另外一個構造方法,用法是this(參數列表),這個僅僅在類的構造方法中,別的地方不能這麼用。
②函數參數或者函數中的局部變量和成員變量同名的狀況下,成員變量被屏蔽,此時要訪問成員變量則須要用「this.成員變量名」的方式來引用成員變量。固然,在沒有同名的狀況下,能夠直接用成員變量的名字,而不用this,用了也不爲錯,呵呵。
③在函數中,須要引用該函所屬類的當前對象時候,直接用this。
設計

以上3點能夠再簡化爲2點,就是①是一個用法,即:this表明當前時刻正在建立的對象;②③是一個用法,即:this表明當前時刻正在調用該成員方法的對象。指針

總而言之,this的這三個用法都是從對「this是指向對象自己的一個指針」這句話的更深刻的理解而來的,死記的話容易忘記並且容易搞錯,要理解!code

2、super關鍵字

super關鍵和this關鍵字的做用相似,是使被屏蔽的成員變量或者成員方法變爲可見,或者說用來引用被屏蔽的成員變量或者成員方法。
不過super是用在子類中,目的是訪問直接父類中被屏蔽的成員,注意是直接父類(就是類之上最近的超類)。下面是一個綜合運用super的例子,有兩個類:一個Father類,一個Father類的子類Son,經過這兩個類徹底演示了super的用法,一下是代碼:
對象

package org.leizhimin; public class Father {       
    public String v="Father";       
    public String x="輸出了Father類的public成員變量x!!!";            
    public Father() {          
        System.out.println("Father構造方法被調用!");     
    }          
    public Father(String v) {            
        this.v="Father類的帶參數構造方法!運行了.";     
    }         
    public void outinfo() {            
        System.out.println("Father的outinfo方法被調用");     
    }          
    public static void main(String[] args) {            
        // TODO 自動生成方法存根     
    } 
}   
package org.leizhimin; 
public class Son extends Father {     
    public String v="Son";               
    public Son() {            
        super();      
        //調用超類的構造方法,只能放到第一行.            
        System.out.println("Son無參數構造方法被調用!");            
        //super();      //錯誤的,必須放到構造方法體的最前面.     
    }           
    public Son(String str) {            
        super(str);            
        System.out.println("Son帶參數構造方法被調用!");     
    }         
    // 覆蓋了超類成員方法outinfo()    
    public void outinfo() {             
        System.out.println("Son的outinfo()方法被調用");     
    }           
    public void test() {            
        String v="哈哈哈哈!";           
        // 局部變量v覆蓋了成員變量v和超類變量v            
        System.out.println("------1-----");          
        System.out.println(v);           // 輸出局部變量v          
        System.out.println(this.v);          // 輸出(子類)成員變量v          
        System.out.println(super.v);         // 輸出超類成員變量v             
        System.out.println("------2-----");          
        System.out.println(x);           // 輸出超類成員變量v,子類繼承而來          
        System.out.println(super.x); //輸出超類成員變量v            
        System.out.println("------3-----");          
        outinfo();           // 調用子類的outinfo()方法  
        this.outinfo();  //調用子類的outinfo()方法          
        super.outinfo(); //調用父類的outinfo()方法     
    }           
    public static void main(String[] args) {          
        new Son().test();       
    } 
}

 

 

子類Son運行結果:繼承

 

Father構造方法被調用!
Son無參數構造方法被調用!
------1-----
哈哈哈哈!
Son
Father
------2-----
輸出了Father類的public成員變量x!!!
輸出了Father類的public成員變量x!!!
------3-----
Son的outinfo()方法被調用
Son的outinfo()方法被調用
Father的outinfo方法被調用
get

說明:此例子僅僅爲了說明super的用法,實際在設計類的時候通常都儘量地將成員變量私有(private)化。

經過上面的例子,下面總結一下super關鍵字用在三個地方:

第1、super關鍵字在子類構造方法中的使用。

子類的構造方法要調用父類的構造方法,用「super(參數列表)」的方式調用,參數不是必須的。同時還要注意的一點是:「super(參數列表)」這條語句只能用在子類構造方法體中的第一行

第二和第三個的用法比較相近。

第2、當子類方法中的局部變量或者子類的成員變量與父類成員變量同名時,也就是子類局部變量覆蓋父類成員變量時,用「super.成員變量名」來引用父類 成員變量。固然,若是父類的成員變量沒有被覆蓋,也能夠用「super.成員變量名」來引用父類成員變量,不過這是沒必要要的。

第3、當子類的成員方法覆蓋了父類的成員方法時,也就是子類和父類有徹底相同的方法定義(但方法體能夠不一樣),此時,用「super.方法名(參數列表)」的方式調用父類的方法「super.成員方法(參數列表)」通常也寫在子類成員方法中的第一行。

this、super的用法也不過這些,只有理解了其中的原理,纔不會跌入陷阱!

相關文章
相關標籤/搜索