Java中this和super的區(qū)別及this能否調(diào)用到父類使用
前言:
this 和 super 都是 Java 中常見的關(guān)鍵字,雖然二者在很多情況下都可以被省略,但它們在 Java 中所起的作用是不可磨滅的。它們都是用來起指代作用的,每個類在實例化的時候之所以能調(diào)用到 Object 類(Object 類是所有類的父類),全是二者的“功勞”。
1.super 關(guān)鍵字
super 是用來訪問父類實例屬性和方法的。
1.1 super 方法使用
每個實例類如果沒有顯示的指定構(gòu)造方法,那么它會生成一個隱藏的無參構(gòu)造方法。對于 super() 方法也是類似,如果沒有顯示指定 super() 方法,那么子類會生成一個隱藏的 super() 方法,用來調(diào)用父類的無參構(gòu)造方法,這就是咱們開篇所說的“每個類在實例化的時候之所以能調(diào)用到 Object 類,就是默認 super 方法起作用了”,接下來我們通過實例來驗證一下這個說法。
PS:所謂的“顯示”,是指在程序中主動的調(diào)用,也就是在程序中添加相應的執(zhí)行代碼。
public class SuperExample { // 測試方法 public static void main(String[] args) { Son son = new Son(); } } /** * 父類 */ class Father { public Father() { System.out.println("執(zhí)行父類的構(gòu)造方法"); } } /** * 子類 */ class Son extends Father { }
在以上代碼中,子類 Son 并沒有顯示指定 super() 方法,我們運行以上程序,執(zhí)行的結(jié)果如下:
從上述的打印結(jié)果可以看出,子類 Son 在沒有顯示指定 super() 方法的情況下,竟然調(diào)用了父類的無參構(gòu)造方法,這樣從側(cè)面驗證了,如果子類沒有顯示指定 super() 方法,那么它也會生成一個隱藏的 super() 方法。這一點我們也可以從此類生成的字節(jié)碼文件中得到證實,
如下圖所示:
super 方法注意事項:
如果顯示使用 super() 方法,那么 super() 方法必須放在構(gòu)造方法的首行,否則編譯器會報錯,
如下代碼所示:
如上圖看到的那樣,如果 super() 方法沒有放在首行,那么編譯器就會報錯:提示 super() 方法必須放到構(gòu)造方法的首行。 為什么要把 super() 方法放在首行呢? 這是因為,只要將 super() 方法放在首行,那么在實例化子類時才能確保父類已經(jīng)被先初始化了。
1.2 super 屬性使用
使用 super 還可以調(diào)用父類的屬性,比如以下代碼可以通過子類 Son 調(diào)用父類中的 age 屬性,
實現(xiàn)代碼如下:
public class SuperExample { // 測試方法 public static void main(String[] args) { Son son = new Son(); } } /** * 父類 */ class Father { // 定義一個 age 屬性 public int age = 30; public Father() { super(); System.out.println("執(zhí)行父類的構(gòu)造方法"); } } /** * 子類 */ class Son extends Father { public Son() { System.out.println("父類 age:" + super.age); } }
以上程序的執(zhí)行結(jié)果如下圖所示,在子類中成功地獲取到了父類中的 age 屬性:
2.this 關(guān)鍵字
this 是用來訪問本類實例屬性和方法的,它會先從本類中找,如果本類中找不到則在父類中找。
2.1 this 屬性使用
this 最常見的用法是用來賦值本類屬性的,比如常見的 setter 方法,如下代碼所示:
上述代碼中 this.name 表示 Person 類的 name 屬性,此處的 this 關(guān)鍵字不能省略,如果省略就相當于給當前的局部變量 name 賦值 name,自己給自己賦值了。我們可以嘗試一下,將 this 關(guān)鍵字取消掉,
實現(xiàn)代碼如下:
class Person { private String name; public void setName(String name) { this.name = name; } public String getName() { return name; } } public class ThisExample { public static void main(String[] args) { Person p = new Person(); p.setName("磊哥"); System.out.println(p.getName()); } }
以上程序的執(zhí)行結(jié)果如下圖所示:
從上述結(jié)果可以看出,將 this 關(guān)鍵字去掉之后,賦值失敗,Person 對象中的 name 屬性就為 null 了。
2.2 this 方法使用
我們可以使用 this() 方法來調(diào)用本類中的構(gòu)造方法,具體實現(xiàn)代碼如下:
public class ThisExample { // 測試方法 public static void main(String[] args) { Son p = new Son("Java"); } } /** * 父類 */ class Father { public Father() { System.out.println("執(zhí)行父類的構(gòu)造方法"); } } /** * 子類 */ class Son extends Father { public Son() { System.out.println("子類中的無參構(gòu)造方法"); } public Son(String name) { // 使用 this 調(diào)用本類中無參的構(gòu)造方法 this(); System.out.println("子類有參構(gòu)造方法,name:" + name); } }
以上程序的執(zhí)行結(jié)果如下圖所示:
從上述結(jié)果中可以看出,通過 this() 方法成功調(diào)用到了本類中的無參構(gòu)造方法。
注意:this() 方法和 super() 方法的使用規(guī)則一樣,如果顯示的調(diào)用,只能放在方法的首行。
2.3 this 訪問父類方法
接下來,我們嘗試使用 this 訪問父類方法,具體實現(xiàn)代碼如下:
public class ThisExample { public static void main(String[] args) { Son son = new Son(); son.sm(); } } /** * 父類 */ class Father { public void fm() { System.out.println("調(diào)用了父類中的 fm() 方法"); } } /** * 子類 */ class Son extends Father { public void sm() { System.out.println("調(diào)用子類的 sm() 方法訪問父類方法"); // 調(diào)用父類中的方法 this.fm(); } }
以上程序的執(zhí)行結(jié)果如下:
從上述結(jié)果可以看出,使用 this 是可以訪問到父類中的方法的,this 會先從本類中找,如果找不到則會去父類中找。
3.this 和 super 的區(qū)別
3.1 指代的對象不同
super 指代的是父類,是用來訪問父類的;而 this 指代的是當前類。
3.2 查找范圍不同
super 只能查找父類,而 this 會先從本類中找,如果找不到則會去父類中找。
3.3 本類屬性賦值不同
this 可以用來為本類的實例屬性賦值,而 super 則不能實現(xiàn)此功能。
3.4 this 可用于 synchronized
因為 this 表示當前對象,所以this 可用于 synchronized(this){....} 加鎖,而 super 則不能實現(xiàn)此功能。
總結(jié)
this 和 super 都是 Java 中的關(guān)鍵字,都起指代作用,當顯示使用它們時,都需要將它們放在方法的首行(否則編譯器會報錯)。this 表示當前對象,super 用來指代父類對象,它們有四點不同:指代對象、查找訪問、本類屬性賦值和 synchronized 的使用不同。
到此這篇關(guān)于Java中this和super的區(qū)別及this能否調(diào)用到父類使用的文章就介紹到這了,更多相關(guān)this和super 區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SMBMS超市訂單管理系統(tǒng)的網(wǎng)站源碼
這篇文章主要介紹了SMBMS超市訂單管理系統(tǒng),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-05-05Java編程之多線程死鎖與線程間通信簡單實現(xiàn)代碼
這篇文章主要介紹了Java編程之多線程死鎖與線程間通信簡單實現(xiàn)代碼,具有一定參考價值,需要的朋友可以了解下。2017-10-10SpringBoot如何整合redis實現(xiàn)過期key監(jiān)聽事件
這篇文章主要介紹了SpringBoot如何整合redis實現(xiàn)過期key監(jiān)聽事件,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-09-09Java并發(fā)之原子性 有序性 可見性及Happen Before原則
一提到happens-before原則,就讓人有點“丈二和尚摸不著頭腦”。這個涵蓋了整個JMM中可見性原則的規(guī)則,究竟如何理解,把我個人一些理解記錄下來。下面可以和小編一起學習Java 并發(fā)四個原則2021-09-09