一、this
Java關鍵字this只能用於方法體內,表示對“調用方法的那個對象”的引用。當一個對象創建後,Java虛擬機(JVM)就會給這個對象分配一個引用自身的指針,這個指針的名字就是this。因此,this只能在類中的非靜態方法中使用,靜態方法和靜態的代碼塊中絕對不能出現this,並且this只和特定的對象關聯,而不和類關聯,同一個類的不同對象有不同的this。
第一、通過this調用另一個構造方法,用法是this(參數列表),這個僅僅在類的構造方法中,別的地方不能這麼用。儘管可用this 調用一個構造器,但不可調用兩個。除構造器之外,編譯器禁止在其它任何方法中調用構造器。
第二、函數參數或者函數中的局部變量和成員變量同名的情況下,成員變量被屏蔽,此時要訪問成員變量則需要用“this.成員變量名”的方式來引用成員變量。當然,在沒有同名的情況下,可以直接用成員變量的名字,而不用this,用了也不爲錯。
第三、在函數中,需要引用該函所屬類的當前對象時候,直接用this。
下面給出一個使用this的綜合實例,以便說明問題:
- public class test {
- private int number;
- private String username;
- private String password;
- private int x = 100;
- public test(int n) {
- number = n; // 這個還可以寫爲: this.number=n;
- }
- public test(int i, String username, String password) {
- // 成員變量和參數同名,成員變量被屏蔽,用"this.成員變量"的方式訪問成員變量.
- this.username = username;
- this.password = password;
- }
- // 默認不帶參數的構造方法
- public test() {
- this(0, "未知", "空"); // 通過this調用另一個構造方法
- //this(1); //儘管可用this調用一個構造器,但不可調用兩個
- }
- public test(String name) {
- this(1, name, "空"); // 通過this調用另一個構造方法
- }
- private void f() {
- // 局部變量與成員變量同名,成員變量被屏蔽,用"this.成員變量"的方式訪問成員變量.
- int x;
- x = this.x++;
- System.out.println(x);
- System.out.println(this.x);
- }
- // 返回當前實例的引用
- private test getSelf() {
- return this;
- }
- private void outinfo(test t) {
- System.out.println("-----------");
- System.out.println(t.number);
- System.out.println(t.username);
- System.out.println(t.password);
- f(); // 這個可以寫爲: this.f();
- }
- public static void main(String args[]) {
- test t1 = new test();
- test t2 = new test("遊客");
- t1.outinfo(t1);
- t2.outinfo(t2);
- }
- }
- -----------
- 0
- 未知
- 空
- 100
- 101
- -----------
- 0
- 遊客
- 空
- 100
- 101
二、spuer
super關鍵字和this作用類似,使被屏蔽的成員變量或者成員方法變爲可見,或者說用來引用被屏蔽的成員變量和成員成員方法。不過super是用在子類中,目的是訪問直接父類中被屏蔽的成員,注意是直接父類(就是類之上最近的超類)。
第一、在子類構造方法中要調用父類的構造方法,用“super(參數列表)”的方式調用,參數不是必須的。同時還要注意的一點是:“super(參數列表)”這條語句只能用在子類構造方法體中的第一行。
第二、當子類方法中的局部變量或者子類的成員變量與父類成員變量同名時,也就是子類局部變量覆蓋父類成員變量時,用“super.成員變量名”來引用父類成員變量。當然,如果父類的成員變量沒有被覆蓋,也可以用“super.成員變量名”來引用父類成員變量,不過這是不必要的。
第三、當子類的成員方法覆蓋(重寫)了父類的成員方法時,也就是子類和父類有完全相同的方法定義(但方法體可以不同),此時,用“super.方法名(參數列表)”的方式訪問父類的方法。
下面是一個綜合運用super的例子,有兩個類:一個Father類,一個Father類的子類Son,通過這兩個類完全演示了super的用法:
- 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 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();
- }
- }
- Father構造方法被調用!
- Son無參數構造方法被調用!
- ------1-----
- 哈哈哈哈!
- Son
- Father
- ------2-----
- 輸出了Father類的public成員變量x!!!
- 輸出了Father類的public成員變量x!!!
- ------3-----
- Son的outinfo()方法被調用
- Son的outinfo()方法被調用
- Father的outinfo方法被調用
使用super&this應該注意些什麼?
1)調用super()必須寫在子類構造方法的第一行,否則編譯不通過。每個子類構造方法的第一條語句,都是隱含地調用super(),如果父類沒有這種形式的構造函數,那麼在編譯的時候就會報錯。
2)super()和this()類似,區別是,super從子類中調用父類的構造方法,this()在同一類內調用其它方法。
3)super()和this()均需放在構造方法內第一行。
4)儘管可以用this調用一個構造器,但卻不能調用兩個。
5)this和super不能同時出現在一個構造函數裏面,因爲this必然會調用其它的構造函數,其它的構造函數必然也會有super語句的存在,所以在同一個構造函數裏面有相同的語句,就失去了語句的意義,編譯器也不會通過。
6)this()和super()都指的是對象,所以,均不可以在static環境中使用。包括:static變量,static方法,static語句塊。
7)從本質上講,this是一個指向本對象的指針, 然而super是一個Java關鍵字。